summaryrefslogtreecommitdiff
path: root/op_crates/fetch/22_body.js
diff options
context:
space:
mode:
Diffstat (limited to 'op_crates/fetch/22_body.js')
-rw-r--r--op_crates/fetch/22_body.js338
1 files changed, 0 insertions, 338 deletions
diff --git a/op_crates/fetch/22_body.js b/op_crates/fetch/22_body.js
deleted file mode 100644
index 938e3023e..000000000
--- a/op_crates/fetch/22_body.js
+++ /dev/null
@@ -1,338 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-
-// @ts-check
-/// <reference path="../webidl/internal.d.ts" />
-/// <reference path="../url/internal.d.ts" />
-/// <reference path="../url/lib.deno_url.d.ts" />
-/// <reference path="../web/internal.d.ts" />
-/// <reference path="../file/internal.d.ts" />
-/// <reference path="../file/lib.deno_file.d.ts" />
-/// <reference path="./internal.d.ts" />
-/// <reference path="./11_streams_types.d.ts" />
-/// <reference path="./lib.deno_fetch.d.ts" />
-/// <reference lib="esnext" />
-"use strict";
-
-((window) => {
- const core = window.Deno.core;
- const webidl = globalThis.__bootstrap.webidl;
- const { parseUrlEncoded } = globalThis.__bootstrap.url;
- const { parseFormData, formDataFromEntries, encodeFormData } =
- globalThis.__bootstrap.formData;
- const mimesniff = globalThis.__bootstrap.mimesniff;
- const { isReadableStreamDisturbed } = globalThis.__bootstrap.streams;
-
- class InnerBody {
- /** @type {ReadableStream<Uint8Array> | { body: Uint8Array, consumed: boolean }} */
- streamOrStatic;
- /** @type {null | Uint8Array | Blob | FormData} */
- source = null;
- /** @type {null | number} */
- length = null;
-
- /**
- * @param {ReadableStream<Uint8Array> | { body: Uint8Array, consumed: boolean }} stream
- */
- constructor(stream) {
- this.streamOrStatic = stream ??
- { body: new Uint8Array(), consumed: false };
- }
-
- get stream() {
- if (!(this.streamOrStatic instanceof ReadableStream)) {
- const { body, consumed } = this.streamOrStatic;
- this.streamOrStatic = new ReadableStream({
- start(controller) {
- controller.enqueue(body);
- controller.close();
- },
- });
- if (consumed) {
- this.streamOrStatic.cancel();
- }
- }
- return this.streamOrStatic;
- }
-
- /**
- * https://fetch.spec.whatwg.org/#body-unusable
- * @returns {boolean}
- */
- unusable() {
- if (this.streamOrStatic instanceof ReadableStream) {
- return this.streamOrStatic.locked ||
- isReadableStreamDisturbed(this.streamOrStatic);
- }
- return this.streamOrStatic.consumed;
- }
-
- /**
- * @returns {boolean}
- */
- consumed() {
- if (this.streamOrStatic instanceof ReadableStream) {
- return isReadableStreamDisturbed(this.streamOrStatic);
- }
- return this.streamOrStatic.consumed;
- }
-
- /**
- * https://fetch.spec.whatwg.org/#concept-body-consume-body
- * @returns {Promise<Uint8Array>}
- */
- async consume() {
- if (this.unusable()) throw new TypeError("Body already consumed.");
- if (this.streamOrStatic instanceof ReadableStream) {
- const reader = this.stream.getReader();
- /** @type {Uint8Array[]} */
- const chunks = [];
- let totalLength = 0;
- while (true) {
- const { value: chunk, done } = await reader.read();
- if (done) break;
- chunks.push(chunk);
- totalLength += chunk.byteLength;
- }
- const finalBuffer = new Uint8Array(totalLength);
- let i = 0;
- for (const chunk of chunks) {
- finalBuffer.set(chunk, i);
- i += chunk.byteLength;
- }
- return finalBuffer;
- } else {
- this.streamOrStatic.consumed = true;
- return this.streamOrStatic.body;
- }
- }
-
- /**
- * @returns {InnerBody}
- */
- clone() {
- const [out1, out2] = this.stream.tee();
- this.streamOrStatic = out1;
- const second = new InnerBody(out2);
- second.source = core.deserialize(core.serialize(this.source));
- second.length = this.length;
- return second;
- }
- }
-
- /**
- * @param {any} prototype
- * @param {symbol} bodySymbol
- * @param {symbol} mimeTypeSymbol
- * @returns {void}
- */
- function mixinBody(prototype, bodySymbol, mimeTypeSymbol) {
- function consumeBody(object) {
- if (object[bodySymbol] !== null) {
- return object[bodySymbol].consume();
- }
- return Promise.resolve(new Uint8Array());
- }
-
- /** @type {PropertyDescriptorMap} */
- const mixin = {
- body: {
- /**
- * @returns {ReadableStream<Uint8Array> | null}
- */
- get() {
- webidl.assertBranded(this, prototype);
- if (this[bodySymbol] === null) {
- return null;
- } else {
- return this[bodySymbol].stream;
- }
- },
- },
- bodyUsed: {
- /**
- * @returns {boolean}
- */
- get() {
- webidl.assertBranded(this, prototype);
- if (this[bodySymbol] !== null) {
- return this[bodySymbol].consumed();
- }
- return false;
- },
- },
- arrayBuffer: {
- /** @returns {Promise<ArrayBuffer>} */
- value: async function arrayBuffer() {
- webidl.assertBranded(this, prototype);
- const body = await consumeBody(this);
- return packageData(body, "ArrayBuffer");
- },
- },
- blob: {
- /** @returns {Promise<Blob>} */
- value: async function blob() {
- webidl.assertBranded(this, prototype);
- const body = await consumeBody(this);
- return packageData(body, "Blob", this[mimeTypeSymbol]);
- },
- },
- formData: {
- /** @returns {Promise<FormData>} */
- value: async function formData() {
- webidl.assertBranded(this, prototype);
- const body = await consumeBody(this);
- return packageData(body, "FormData", this[mimeTypeSymbol]);
- },
- },
- json: {
- /** @returns {Promise<any>} */
- value: async function json() {
- webidl.assertBranded(this, prototype);
- const body = await consumeBody(this);
- return packageData(body, "JSON");
- },
- },
- text: {
- /** @returns {Promise<string>} */
- value: async function text() {
- webidl.assertBranded(this, prototype);
- const body = await consumeBody(this);
- return packageData(body, "text");
- },
- },
- };
- return Object.defineProperties(prototype.prototype, mixin);
- }
-
- const decoder = new TextDecoder();
-
- /**
- * https://fetch.spec.whatwg.org/#concept-body-package-data
- * @param {Uint8Array} bytes
- * @param {"ArrayBuffer" | "Blob" | "FormData" | "JSON" | "text"} type
- * @param {MimeType | null} [mimeType]
- */
- function packageData(bytes, type, mimeType) {
- switch (type) {
- case "ArrayBuffer":
- return bytes.buffer;
- case "Blob":
- return new Blob([bytes], {
- type: mimeType !== null ? mimesniff.serializeMimeType(mimeType) : "",
- });
- case "FormData": {
- if (mimeType !== null) {
- if (mimeType !== null) {
- const essence = mimesniff.essence(mimeType);
- if (essence === "multipart/form-data") {
- const boundary = mimeType.parameters.get("boundary");
- if (boundary === null) {
- throw new TypeError(
- "Missing boundary parameter in mime type of multipart formdata.",
- );
- }
- return parseFormData(bytes, boundary);
- } else if (essence === "application/x-www-form-urlencoded") {
- const entries = parseUrlEncoded(bytes);
- return formDataFromEntries(
- entries.map((x) => ({ name: x[0], value: x[1] })),
- );
- }
- }
- throw new TypeError("Invalid form data");
- }
- throw new TypeError("Missing content type");
- }
- case "JSON":
- return JSON.parse(decoder.decode(bytes));
- case "text":
- return decoder.decode(bytes);
- }
- }
-
- const encoder = new TextEncoder();
-
- /**
- * @param {BodyInit} object
- * @returns {{body: InnerBody, contentType: string | null}}
- */
- function extractBody(object) {
- /** @type {ReadableStream<Uint8Array> | { body: Uint8Array, consumed: boolean }} */
- let stream;
- let source = null;
- let length = null;
- let contentType = null;
- if (object instanceof Blob) {
- stream = object.stream();
- source = object;
- length = object.size;
- if (object.type.length !== 0) {
- contentType = object.type;
- }
- } else if (ArrayBuffer.isView(object) || object instanceof ArrayBuffer) {
- const u8 = ArrayBuffer.isView(object)
- ? new Uint8Array(
- object.buffer,
- object.byteOffset,
- object.byteLength,
- )
- : new Uint8Array(object);
- const copy = u8.slice(0, u8.byteLength);
- source = copy;
- } else if (object instanceof FormData) {
- const res = encodeFormData(object);
- stream = { body: res.body, consumed: false };
- source = object;
- length = res.body.byteLength;
- contentType = res.contentType;
- } else if (object instanceof URLSearchParams) {
- source = encoder.encode(object.toString());
- contentType = "application/x-www-form-urlencoded;charset=UTF-8";
- } else if (typeof object === "string") {
- source = encoder.encode(object);
- contentType = "text/plain;charset=UTF-8";
- } else if (object instanceof ReadableStream) {
- stream = object;
- if (object.locked || isReadableStreamDisturbed(object)) {
- throw new TypeError("ReadableStream is locked or disturbed");
- }
- }
- if (source instanceof Uint8Array) {
- stream = { body: source, consumed: false };
- length = source.byteLength;
- }
- const body = new InnerBody(stream);
- body.source = source;
- body.length = length;
- return { body, contentType };
- }
-
- webidl.converters["BodyInit"] = (V, opts) => {
- // Union for (ReadableStream or Blob or ArrayBufferView or ArrayBuffer or FormData or URLSearchParams or USVString)
- if (V instanceof ReadableStream) {
- // TODO(lucacasonato): ReadableStream is not branded
- return V;
- } else if (V instanceof Blob) {
- return webidl.converters["Blob"](V, opts);
- } else if (V instanceof FormData) {
- return webidl.converters["FormData"](V, opts);
- } else if (V instanceof URLSearchParams) {
- // TODO(lucacasonato): URLSearchParams is not branded
- return V;
- }
- if (typeof V === "object") {
- if (V instanceof ArrayBuffer || V instanceof SharedArrayBuffer) {
- return webidl.converters["ArrayBuffer"](V, opts);
- }
- if (ArrayBuffer.isView(V)) {
- return webidl.converters["ArrayBufferView"](V, opts);
- }
- }
- return webidl.converters["USVString"](V, opts);
- };
- webidl.converters["BodyInit?"] = webidl.createNullableConverter(
- webidl.converters["BodyInit"],
- );
-
- window.__bootstrap.fetchBody = { mixinBody, InnerBody, extractBody };
-})(globalThis);