import { ajax } from 'rxjs/ajax';
import { catchError, map } from 'rxjs/operators';
import { createAggregateError, normalizeAjaxError } from '../util/errors';
export const graphQLContent = Symbol('graphQLContent');
/**
 * Guarantees that the GraphQL query resulted in an error.
 */
export function isGraphQLError(result) {
    return !!result.errors && result.errors.length > 0;
}
export function dataOrThrowErrors(result) {
    if (isGraphQLError(result)) {
        throw createAggregateError(result.errors);
    }
    return result.data;
}
export const createInvalidGraphQLQueryResponseError = (queryName) => Object.assign(new Error(`Invalid GraphQL response: query ${queryName}`), {
    queryName,
});
export const createInvalidGraphQLMutationResponseError = (queryName) => Object.assign(new Error(`Invalid GraphQL response: mutation ${queryName}`), {
    queryName,
});
/**
 * Use this template string tag for all GraphQL queries
 */
export const gql = (template, ...substitutions) => ({
    [graphQLContent]: String.raw(template, ...substitutions.map(s => s[graphQLContent] || s)),
});
/**
 * Does a GraphQL request to the Sourcegraph GraphQL API running under `/.api/graphql`
 *
 * @param request The GraphQL request (query or mutation)
 * @param variables A key/value object with variable values
 * @return Observable That emits the result or errors if the HTTP request failed
 */
function requestGraphQL(request, variables = {}) {
    const nameMatch = request[graphQLContent].match(/^\s*(?:query|mutation)\s+(\w+)/);
    return ajax({
        method: 'POST',
        url: '/.api/graphql' + (nameMatch ? '?' + nameMatch[1] : ''),
        headers: Object.assign({}, window.context.xhrHeaders, { Accept: 'application/json', 'Content-Type': 'application/json' }),
        body: JSON.stringify({ query: request[graphQLContent], variables }),
    }).pipe(catchError(err => {
        normalizeAjaxError(err);
        throw err;
    }), map(({ response }) => response));
}
/**
 * Does a GraphQL query to the Sourcegraph GraphQL API running under `/.api/graphql`
 *
 * @param query The GraphQL query
 * @param variables A key/value object with variable values
 * @return Observable That emits the result or errors if the HTTP request failed
 */
export function queryGraphQL(query, variables = {}) {
    return requestGraphQL(query, variables);
}
/**
 * Does a GraphQL mutation to the Sourcegraph GraphQL API running under `/.api/graphql`
 *
 * @param mutation The GraphQL mutation
 * @param variables A key/value object with variable values
 * @return Observable That emits the result or errors if the HTTP request failed
 */
export function mutateGraphQL(mutation, variables = {}) {
    return requestGraphQL(mutation, variables);
}
//# sourceMappingURL=graphql.js.map