"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;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parsePathOrGlob = exports.normalizeInput = exports.maybeFilePath = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const constants_1 = require("./constants");
/**
 * Determines if a string is a valid file path.
 * @param str - The string to check.
 * @returns True if the string is a valid file path, false otherwise.
 */
function maybeFilePath(str) {
    if (typeof str !== 'string') {
        throw new Error(`Invalid input: ${JSON.stringify(str)}`);
    }
    const forbiddenSubstrings = ['\n', 'portkey://', 'langfuse://'];
    if (forbiddenSubstrings.some((substring) => str.includes(substring))) {
        return false;
    }
    return (str.startsWith('file://') ||
        constants_1.VALID_FILE_EXTENSIONS.some((ext) => {
            const tokens = str.split(':'); // str may be file.js:functionName
            // Checks if the second to last token or the last token ends with the extension
            return tokens.pop()?.endsWith(ext) || tokens.pop()?.endsWith(ext);
        }) ||
        str.charAt(str.length - 3) === '.' ||
        str.charAt(str.length - 4) === '.' ||
        str.endsWith('.') ||
        str.includes('*') ||
        str.includes('/') ||
        str.includes('\\'));
}
exports.maybeFilePath = maybeFilePath;
/**
 * Normalizes the input prompt to an array of prompts, rejecting invalid and empty inputs.
 * @param promptPathOrGlobs - The input prompt.
 * @returns The normalized prompts.
 * @throws If the input is invalid or empty.
 */
function normalizeInput(promptPathOrGlobs) {
    if (!promptPathOrGlobs ||
        ((typeof promptPathOrGlobs === 'string' || Array.isArray(promptPathOrGlobs)) &&
            promptPathOrGlobs.length === 0)) {
        throw new Error(`Invalid input prompt: ${JSON.stringify(promptPathOrGlobs)}`);
    }
    if (typeof promptPathOrGlobs === 'string') {
        return [
            {
                raw: promptPathOrGlobs,
            },
        ];
    }
    if (Array.isArray(promptPathOrGlobs)) {
        return promptPathOrGlobs.map((promptPathOrGlob, index) => {
            if (typeof promptPathOrGlob === 'string') {
                return {
                    raw: promptPathOrGlob,
                };
            }
            return {
                raw: promptPathOrGlob.raw || promptPathOrGlob.id,
                ...promptPathOrGlob,
            };
        });
    }
    if (typeof promptPathOrGlobs === 'object' && Object.keys(promptPathOrGlobs).length) {
        /* NOTE: This format is considered legacy and has been deprecated. Example:
          {
            'prompts.txt': 'foo1',
            'prompts.py': 'foo2',
          }
          */
        return Object.entries(promptPathOrGlobs).map(([raw, key]) => ({
            label: key,
            raw: raw,
        }));
    }
    // numbers, booleans, etc
    throw new Error(`Invalid input prompt: ${JSON.stringify(promptPathOrGlobs)}`);
}
exports.normalizeInput = normalizeInput;
/**
 * Parses a file path or glob pattern to extract function names and file extensions.
 * Function names can be specified in the filename like this:
 * prompt.py:myFunction or prompts.js:myFunction.
 * @param basePath - The base path for file resolution.
 * @param promptPath - The path or glob pattern.
 * @returns Parsed details including function name, file extension, and directory status.
 */
function parsePathOrGlob(basePath, promptPath) {
    let filePath = path.join(basePath, promptPath);
    if (filePath.includes('file:')) {
        filePath = filePath.split('file:')[1];
    }
    let stats;
    try {
        stats = fs.statSync(filePath);
    }
    catch (err) {
        if (process.env.PROMPTFOO_STRICT_FILES) {
            throw err;
        }
    }
    let filename = path.parse(filePath).base;
    let functionName;
    if (filename.includes(':')) {
        const splits = filename.split(':');
        if (splits[0] && ['.js', '.cjs', '.mjs', '.py'].some((ext) => splits[0].endsWith(ext))) {
            [filename, functionName] = splits;
        }
    }
    return {
        extension: path.parse(filename).ext,
        functionName,
        isPathPattern: stats?.isDirectory() || /[*?{}\[\]]/.test(filePath), // glob pattern
        promptPath: path.join(basePath, filename),
    };
}
exports.parsePathOrGlob = parsePathOrGlob;
//# sourceMappingURL=utils.js.map