"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseYaml = parseYaml;
exports.parseSingleYaml = parseSingleYaml;
exports.dump = dump;
const yaml_1 = require("yaml");
const logger_1 = require("../logger");
const regex_1 = require("./regex");
/**
 * Parse a YAML string into a JavaScript object.
 *
 * Multiple documents are supported.
 *
 * If a schema is provided, the parsed object will be validated against it.
 *
 * If failureBehaviour is set to 'filter',
 *      the function will return an empty array if the YAML parsing or schema validation fails and therefore will not throw an error.
 *
 * If failureBehaviour is set to 'throw',
 *      the function will throw an error if the YAML parsing or schema validation fails for ANY document.
 * @param content
 * @param options
 */
function parseYaml(content, options) {
    const massagedContent = massageContent(content, options);
    const rawDocuments = (0, yaml_1.parseAllDocuments)(massagedContent, prepareParseOption(options));
    const schema = options?.customSchema;
    const results = [];
    for (const rawDocument of rawDocuments) {
        const errors = rawDocument.errors;
        // handle YAML parse errors
        if (errors?.length) {
            const error = new AggregateError(errors, 'Failed to parse YAML file');
            if (options?.failureBehaviour === 'filter') {
                logger_1.logger.debug(`Failed to parse YAML file: ${error.message}`);
                continue;
            }
            throw error;
        }
        const document = rawDocument.toJS({ maxAliasCount: 10000 });
        // skip schema validation if no schema is provided
        if (!schema) {
            results.push(document);
            continue;
        }
        const result = schema.safeParse(document);
        if (result.success) {
            results.push(result.data);
            continue;
        }
        // handle schema validation errors
        if (options?.failureBehaviour === 'filter') {
            logger_1.logger.trace({ error: result.error, document }, 'Failed to parse schema for YAML');
            continue;
        }
        throw new Error('Failed to parse YAML file', { cause: result.error });
    }
    return results;
}
/**
 * Parse a YAML string into a JavaScript object.
 *
 * Only a single document is supported.
 *
 * If a schema is provided, the parsed object will be validated against it.
 * Should the YAML parsing or schemata validation fail, an error will be thrown.
 *
 * @param content
 * @param options
 */
function parseSingleYaml(content, options) {
    const massagedContent = massageContent(content, options);
    const rawDocument = (0, yaml_1.parseDocument)(massagedContent, prepareParseOption(options));
    if (rawDocument?.errors?.length) {
        throw new AggregateError(rawDocument.errors, 'Failed to parse YAML file');
    }
    const document = rawDocument.toJS({ maxAliasCount: 10000 });
    const schema = options?.customSchema;
    if (!schema) {
        return document;
    }
    return schema.parse(document);
}
function dump(obj, opts) {
    return (0, yaml_1.stringify)(obj, opts);
}
function massageContent(content, options) {
    if (options?.removeTemplates) {
        return content
            .replace((0, regex_1.regEx)(/\s+{{.+?}}:.+/gs), '')
            .replace((0, regex_1.regEx)(/{{`.+?`}}/gs), '')
            .replace((0, regex_1.regEx)(/{{.+?}}/gs), '')
            .replace((0, regex_1.regEx)(/{%`.+?`%}/gs), '')
            .replace((0, regex_1.regEx)(/{%.+?%}/g), '');
    }
    return content;
}
function prepareParseOption(options) {
    return {
        prettyErrors: true,
        // if we're removing templates, we can run into the situation where we have duplicate keys
        uniqueKeys: !options?.removeTemplates,
        strict: false,
        ...options,
    };
}
//# sourceMappingURL=yaml.js.map