"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createSchemaFetch = void 0;
const graphql_1 = require("graphql");
const client_1 = require("@apollo/client");
const testing_1 = require("@apollo/client/testing");
const internal_1 = require("@apollo/client/testing/internal");
/**
 * A function that accepts a static `schema` and a `mockFetchOpts` object and
 * returns a disposable object with `mock` and `restore` functions.
 *
 * The `mock` function is a mock fetch function that is set on the global
 * `window` object. This function intercepts any fetch requests and
 * returns a response by executing the operation against the provided schema.
 *
 * The `restore` function is a cleanup function that will restore the previous
 * `fetch`. It is automatically called if the function's return value is
 * declared with `using`. If your environment does not support the language
 * feature `using`, you should manually invoke the `restore` function.
 *
 * @param schema - A `GraphQLSchema`.
 * @param mockFetchOpts - Configuration options.
 * @returns An object with both `mock` and `restore` functions.
 *
 * @example
 * ```js
 * using _fetch = createSchemaFetch(schema); // automatically restores fetch after exiting the block
 *
 * const { restore } = createSchemaFetch(schema);
 * restore(); // manually restore fetch if `using` is not supported
 * ```
 * @since 3.10.0
 * @alpha
 * @deprecated `createSchemaFetch` is deprecated and will be removed in 3.12.0.
 * Please migrate to [`@apollo/graphql-testing-library`](https://github.com/apollographql/graphql-testing-library).
 */
const createSchemaFetch = (schema, mockFetchOpts = { validate: true }) => {
    const prevFetch = window.fetch;
    const delayMin = mockFetchOpts.delay?.min ?? 3;
    const delayMax = mockFetchOpts.delay?.max ?? delayMin + 2;
    if (delayMin > delayMax) {
        throw new Error("Please configure a minimum delay that is less than the maximum delay. The default minimum delay is 3ms.");
    }
    const mockFetch = async (_uri, options) => {
        if (delayMin > 0) {
            const randomDelay = Math.random() * (delayMax - delayMin) + delayMin;
            await (0, testing_1.wait)(randomDelay);
        }
        const body = JSON.parse(options.body);
        const document = (0, client_1.gql)(body.query);
        if (mockFetchOpts.validate) {
            let validationErrors = [];
            try {
                validationErrors = (0, graphql_1.validate)(schema, document);
            }
            catch (e) {
                validationErrors = [
                    e instanceof Error ?
                        graphql_1.GraphQLError.prototype.toJSON.apply(e)
                        : e,
                ];
            }
            if (validationErrors?.length > 0) {
                return new Response(JSON.stringify({ errors: validationErrors }));
            }
        }
        const result = await (0, graphql_1.execute)({
            schema,
            document,
            variableValues: body.variables,
            operationName: body.operationName,
        });
        const stringifiedResult = JSON.stringify(result);
        return new Response(stringifiedResult);
    };
    function mockGlobal() {
        window.fetch = mockFetch;
        const restore = () => {
            if (window.fetch === mockFetch) {
                window.fetch = prevFetch;
            }
        };
        return (0, internal_1.withCleanup)({ restore }, restore);
    }
    return Object.assign(mockFetch, {
        mockGlobal,
        // if https://github.com/rbuckton/proposal-using-enforcement lands
        // [Symbol.enter]: mockGlobal
    });
};
exports.createSchemaFetch = createSchemaFetch;
//# sourceMappingURL=createSchemaFetch.cjs.map
