var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncValues = (this && this.__asyncValues) || function (o) {
    if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
    var m = o[Symbol.asyncIterator], i;
    return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
    if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
    var g = generator.apply(thisArg, _arguments || []), i, q = [];
    return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
    function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
    function fulfill(value) { resume("next", value); }
    function reject(value) { resume("throw", value); }
    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
};
import { visit } from 'graphql';
import { meros } from 'meros';
import { isAsyncIterable, makeAsyncIterableIteratorFromSink, } from '@n1ru4l/push-pull-async-iterable-iterator';
const errorHasCode = (err) => {
    return typeof err === 'object' && err !== null && 'code' in err;
};
export const isSubscriptionWithName = (document, name) => {
    let isSubscription = false;
    visit(document, {
        OperationDefinition(node) {
            var _a;
            if (name === ((_a = node.name) === null || _a === void 0 ? void 0 : _a.value) && node.operation === 'subscription') {
                isSubscription = true;
            }
        },
    });
    return isSubscription;
};
export const createSimpleFetcher = (options, httpFetch) => (graphQLParams, fetcherOpts) => __awaiter(void 0, void 0, void 0, function* () {
    const data = yield httpFetch(options.url, {
        method: 'POST',
        body: JSON.stringify(graphQLParams),
        headers: Object.assign(Object.assign({ 'content-type': 'application/json' }, options.headers), fetcherOpts === null || fetcherOpts === void 0 ? void 0 : fetcherOpts.headers),
    });
    return data.json();
});
export const createWebsocketsFetcherFromUrl = (url, connectionParams) => {
    let wsClient;
    try {
        const { createClient } = require('graphql-ws');
        wsClient = createClient({
            url,
            connectionParams,
        });
        return createWebsocketsFetcherFromClient(wsClient);
    }
    catch (err) {
        if (errorHasCode(err) && err.code === 'MODULE_NOT_FOUND') {
            throw new Error("You need to install the 'graphql-ws' package to use websockets when passing a 'subscriptionUrl'");
        }
        console.error(`Error creating websocket client for ${url}`, err);
    }
};
export const createWebsocketsFetcherFromClient = (wsClient) => (graphQLParams) => makeAsyncIterableIteratorFromSink(sink => wsClient.subscribe(graphQLParams, Object.assign(Object.assign({}, sink), { error(err) {
        if (err instanceof CloseEvent) {
            sink.error(new Error(`Socket closed with event ${err.code} ${err.reason || ''}`.trim()));
        }
        else {
            sink.error(err);
        }
    } })));
export const createLegacyWebsocketsFetcher = (legacyWsClient) => (graphQLParams) => {
    const observable = legacyWsClient.request(graphQLParams);
    return makeAsyncIterableIteratorFromSink(sink => observable.subscribe(sink).unsubscribe);
};
export const createMultipartFetcher = (options, httpFetch) => function (graphQLParams, fetcherOpts) {
    return __asyncGenerator(this, arguments, function* () {
        var e_1, _a;
        const response = yield __await(httpFetch(options.url, {
            method: 'POST',
            body: JSON.stringify(graphQLParams),
            headers: Object.assign(Object.assign({ 'content-type': 'application/json', accept: 'application/json, multipart/mixed' }, options.headers), fetcherOpts === null || fetcherOpts === void 0 ? void 0 : fetcherOpts.headers),
        }).then(r => meros(r, {
            multiple: true,
        })));
        if (!isAsyncIterable(response)) {
            return yield __await(yield yield __await(response.json()));
        }
        try {
            for (var response_1 = __asyncValues(response), response_1_1; response_1_1 = yield __await(response_1.next()), !response_1_1.done;) {
                const chunk = response_1_1.value;
                if (chunk.some(part => !part.json)) {
                    const message = chunk.map(part => `Headers::\n${part.headers}\n\nBody::\n${part.body}`);
                    throw new Error(`Expected multipart chunks to be of json type. got:\n${message}`);
                }
                yield yield __await(chunk.map(part => part.body));
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (response_1_1 && !response_1_1.done && (_a = response_1.return)) yield __await(_a.call(response_1));
            }
            finally { if (e_1) throw e_1.error; }
        }
    });
};
export const getWsFetcher = (options, fetcherOpts) => {
    if (options.wsClient) {
        return createWebsocketsFetcherFromClient(options.wsClient);
    }
    if (options.subscriptionUrl) {
        return createWebsocketsFetcherFromUrl(options.subscriptionUrl, Object.assign(Object.assign({}, options.wsConnectionParams), fetcherOpts === null || fetcherOpts === void 0 ? void 0 : fetcherOpts.headers));
    }
    const legacyWebsocketsClient = options.legacyClient || options.legacyWsClient;
    if (legacyWebsocketsClient) {
        return createLegacyWebsocketsFetcher(legacyWebsocketsClient);
    }
};
//# sourceMappingURL=lib.js.map