import { buildClientSchema, getIntrospectionQuery, parse, } from 'graphql';
import { ValueOrPromise } from 'value-or-promise';
import { createGraphQLError, inspect, isAsyncIterable, } from '@graphql-tools/utils';
function getSchemaFromIntrospection(introspectionResult, options) {
    if (introspectionResult?.data?.__schema) {
        return buildClientSchema(introspectionResult.data, options);
    }
    if (introspectionResult?.errors) {
        const graphqlErrors = introspectionResult.errors.map(error => createGraphQLError(error.message, error));
        if (introspectionResult.errors.length === 1) {
            throw graphqlErrors[0];
        }
        else {
            throw new AggregateError(graphqlErrors, 'Could not obtain introspection result');
        }
    }
    throw createGraphQLError(`Could not obtain introspection result, received the following as response; \n ${inspect(introspectionResult)}`);
}
export function schemaFromExecutor(executor, context, options) {
    const parsedIntrospectionQuery = parse(getIntrospectionQuery(options), options);
    return new ValueOrPromise(() => executor({
        document: parsedIntrospectionQuery,
        context,
    }))
        .then(introspection => {
        if (isAsyncIterable(introspection)) {
            const iterator = introspection[Symbol.asyncIterator]();
            return iterator.next().then(({ value }) => value);
        }
        return introspection;
    })
        .then(introspection => getSchemaFromIntrospection(introspection, options))
        .resolve();
}
