import { print } from "@apollo/client/utilities";
const defaultHttpOptions = {
    includeQuery: true,
    includeExtensions: true,
    preserveHeaderCase: false,
};
const defaultHeaders = {
    // headers are case insensitive (https://stackoverflow.com/a/5259004)
    accept: "application/graphql-response+json,application/json;q=0.9",
    // The content-type header describes the type of the body of the request, and
    // so it typically only is sent with requests that actually have bodies. One
    // could imagine that Apollo Client would remove this header when constructing
    // a GET request (which has no body), but we historically have not done that.
    // This means that browsers will preflight all Apollo Client requests (even
    // GET requests). Apollo Server's CSRF prevention feature (introduced in
    // AS3.7) takes advantage of this fact and does not block requests with this
    // header. If you want to drop this header from GET requests, then you should
    // probably replace it with a `apollo-require-preflight` header, or servers
    // with CSRF prevention enabled might block your GET request. See
    // https://www.apollographql.com/docs/apollo-server/security/cors/#preventing-cross-site-request-forgery-csrf
    // for more details.
    "content-type": "application/json",
};
const defaultOptions = {
    method: "POST",
};
export const fallbackHttpConfig = {
    http: defaultHttpOptions,
    headers: defaultHeaders,
    options: defaultOptions,
};
export const defaultPrinter = (ast, printer) => printer(ast);
export function selectHttpOptionsAndBody(operation, fallbackConfig, ...configs) {
    configs.unshift(fallbackConfig);
    return selectHttpOptionsAndBodyInternal(operation, defaultPrinter, ...configs);
}
export function selectHttpOptionsAndBodyInternal(operation, printer, ...configs) {
    let options = {};
    let http = {};
    configs.forEach((config) => {
        options = {
            ...options,
            ...config.options,
            headers: {
                ...options.headers,
                ...config.headers,
            },
        };
        if (config.credentials) {
            options.credentials = config.credentials;
        }
        options.headers.accept = (config.http?.accept || [])
            .concat(options.headers.accept)
            .join(",");
        http = {
            ...http,
            ...config.http,
        };
    });
    options.headers = removeDuplicateHeaders(options.headers, http.preserveHeaderCase);
    //The body depends on the http options
    const { operationName, extensions, variables, query } = operation;
    const body = { operationName, variables };
    if (http.includeExtensions && Object.keys(extensions || {}).length)
        body.extensions = extensions;
    // not sending the query (i.e persisted queries)
    if (http.includeQuery)
        body.query = printer(query, print);
    return {
        options,
        body,
    };
}
// Remove potential duplicate header names, preserving last (by insertion order).
// This is done to prevent unintentionally duplicating a header instead of
// overwriting it (See #8447 and #8449).
function removeDuplicateHeaders(headers, preserveHeaderCase) {
    // If we're not preserving the case, just remove duplicates w/ normalization.
    if (!preserveHeaderCase) {
        const normalizedHeaders = {};
        Object.keys(Object(headers)).forEach((name) => {
            normalizedHeaders[name.toLowerCase()] = headers[name];
        });
        return normalizedHeaders;
    }
    // If we are preserving the case, remove duplicates w/ normalization,
    // preserving the original name.
    // This allows for non-http-spec-compliant servers that expect intentionally
    // capitalized header names (See #6741).
    const headerData = {};
    Object.keys(Object(headers)).forEach((name) => {
        headerData[name.toLowerCase()] = {
            originalName: name,
            value: headers[name],
        };
    });
    const normalizedHeaders = {};
    Object.keys(headerData).forEach((name) => {
        normalizedHeaders[headerData[name].originalName] = headerData[name].value;
    });
    return normalizedHeaders;
}
//# sourceMappingURL=selectHttpOptionsAndBody.js.map