"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Holder_1 = require("../../../../../Class/Holder");
const fetch_1 = require("../../../../../util/fetch");
const Response_1 = require("../../../../../wrap/Response");
const _ids_1 = require("../../../../_ids");
class Fetch extends Holder_1.Holder {
    constructor(system) {
        super({
            fi: ['url', 'opt', 'body'],
            fo: ['res'],
            i: [],
            o: ['done'],
        }, {
            input: {
                body: {
                    ref: true,
                },
            },
            output: {
                res: {
                    ref: true,
                },
            },
        }, system, _ids_1.ID_FETCH_0);
    }
    async f({ url, opt, body }, done, fail) {
        const { api: { http: { fetch }, }, cache: { interceptors }, } = this.__system;
        opt.body = await body.raw();
        let port;
        try {
            ;
            ({ port } = new URL(url));
        }
        catch (err) {
            fail('invalid url');
            return;
        }
        if ((0, fetch_1.isUnsafePort)(Number.parseInt(port))) {
            fail('unsafe port');
            return;
        }
        const { method = 'GET' } = opt;
        if (method === 'GET' || method === 'HEAD') {
            delete opt.body;
        }
        if (opt.body instanceof ReadableStream) {
            opt.duplex = 'half';
        }
        try {
            fetch(url, opt, interceptors)
                .then((response) => {
                const res = (0, Response_1.wrapResponse)(response, this.__system);
                done({ res });
            })
                .catch((err) => {
                if (err.message === 'Failed to fetch') {
                    fail('failed to fetch');
                    return;
                }
                if (err.message.toLowerCase() ===
                    "failed to execute 'fetch' on 'window': request with get/head method cannot have body.") {
                    fail('GET/HEAD request cannot have body');
                    return;
                }
                if (err.message.startsWith("Failed to execute 'fetch' on 'Window': Failed to parse URL from ")) {
                    fail('failed to parse url');
                    return;
                }
                fail(err.message.toLowerCase());
            });
        }
        catch (err) {
            fail('malformed request');
            return;
        }
    }
    b() {
        this._output.done.push(true);
    }
}
exports.default = Fetch;
//# sourceMappingURL=index.js.map