"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __exportStar = (this && this.__exportStar) || function(m, exports) {
    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.providers = exports.assertions = exports.evaluate = exports.generateTable = void 0;
const tiny_invariant_1 = __importDefault(require("tiny-invariant"));
const assertions_1 = __importDefault(require("./assertions"));
exports.assertions = assertions_1.default;
const providers_1 = __importStar(require("./providers"));
exports.providers = providers_1.default;
const telemetry_1 = __importDefault(require("./telemetry"));
const cache = __importStar(require("./cache"));
const evaluator_1 = require("./evaluator");
const providers_2 = require("./providers");
const testCases_1 = require("./testCases");
const util_1 = require("./util");
const prompts_1 = require("./prompts");
__exportStar(require("./types"), exports);
var table_1 = require("./table");
Object.defineProperty(exports, "generateTable", { enumerable: true, get: function () { return table_1.generateTable; } });
async function evaluate(testSuite, options = {}) {
    const constructedTestSuite = {
        ...testSuite,
        providers: await (0, providers_2.loadApiProviders)(testSuite.providers, {
            env: testSuite.env,
        }),
        tests: await (0, testCases_1.readTests)(testSuite.tests),
        nunjucksFilters: await (0, util_1.readFilters)(testSuite.nunjucksFilters || {}),
        // Full prompts expected (not filepaths)
        prompts: (await Promise.all(testSuite.prompts.map(async (promptInput) => {
            if (typeof promptInput === 'function') {
                return {
                    raw: promptInput.toString(),
                    label: promptInput.toString(),
                    function: promptInput,
                };
            }
            else if (typeof promptInput === 'string') {
                const prompts = await (0, prompts_1.readPrompts)(promptInput);
                return prompts.map((p) => ({
                    raw: p.raw,
                    label: p.label,
                }));
            }
            else {
                return {
                    raw: JSON.stringify(promptInput),
                    label: JSON.stringify(promptInput),
                };
            }
        }))).flat(),
    };
    // Resolve nested providers
    for (const test of constructedTestSuite.tests || []) {
        if (test.options?.provider && typeof test.options.provider === 'function') {
            test.options.provider = await (0, providers_1.loadApiProvider)(test.options.provider);
        }
        if (test.assert) {
            for (const assertion of test.assert) {
                if (assertion.type === 'assert-set' || typeof assertion.provider === 'function') {
                    continue;
                }
                if (assertion.provider) {
                    if (typeof assertion.provider === 'object') {
                        const casted = assertion.provider;
                        (0, tiny_invariant_1.default)(casted.id, 'Provider object must have an id');
                        assertion.provider = await (0, providers_1.loadApiProvider)(casted.id, { options: casted });
                    }
                    else if (typeof assertion.provider === 'string') {
                        assertion.provider = await (0, providers_1.loadApiProvider)(assertion.provider);
                    }
                    else {
                        throw new Error('Invalid provider type');
                    }
                }
            }
        }
    }
    // Other settings
    if (options.cache === false || (options.repeat && options.repeat > 1)) {
        cache.disableCache();
    }
    telemetry_1.default.maybeShowNotice();
    // Run the eval!
    const ret = await (0, evaluator_1.evaluate)(constructedTestSuite, {
        eventSource: 'library',
        ...options,
    });
    const unifiedConfig = { ...testSuite, prompts: constructedTestSuite.prompts };
    let evalId = null;
    if (testSuite.writeLatestResults) {
        await (0, util_1.migrateResultsFromFileSystemToDatabase)();
        evalId = await (0, util_1.writeResultsToDatabase)(ret, unifiedConfig);
    }
    if (testSuite.outputPath) {
        if (typeof testSuite.outputPath === 'string') {
            await (0, util_1.writeOutput)(testSuite.outputPath, evalId, ret, unifiedConfig, null);
        }
        else if (Array.isArray(testSuite.outputPath)) {
            await (0, util_1.writeMultipleOutputs)(testSuite.outputPath, evalId, ret, unifiedConfig, null);
        }
    }
    await telemetry_1.default.send();
    return ret;
}
exports.evaluate = evaluate;
exports.default = {
    evaluate,
    assertions: assertions_1.default,
    providers: providers_1.default,
    cache,
};
//# sourceMappingURL=index.js.map