"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.looseRecord = exports.looseArray = exports.match = exports.reportErrors = void 0;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const hasha_1 = tslib_1.__importDefault(require("hasha"));
const zod_1 = require("zod");
const logger_1 = require("../logger");
const memCache = tslib_1.__importStar(require("./cache/memory"));
const stringify_1 = require("./stringify");
function getCacheKey(error) {
    const content = (0, stringify_1.safeStringify)(error);
    const key = (0, hasha_1.default)(content).slice(0, 32);
    return `err_${key}`;
}
function collectError(schema, error) {
    const { description = 'Unspecified schema' } = schema;
    const schemaErrorsMap = memCache.get('schema-errors') ?? {};
    const schemaErrors = schemaErrorsMap[description] ?? {};
    const key = getCacheKey(error);
    const schemaError = schemaErrors[key];
    if (!schemaError) {
        schemaErrors[key] = error;
        schemaErrorsMap[description] = schemaErrors;
    }
    memCache.set('schema-errors', schemaErrorsMap);
}
function reportErrors() {
    const schemaErrorsMap = memCache.get('schema-errors');
    if (!schemaErrorsMap) {
        return;
    }
    for (const [description, schemaErrors] of Object.entries(schemaErrorsMap)) {
        const errors = Object.values(schemaErrors);
        for (const err of errors) {
            logger_1.logger.warn({ description, err }, `Schema validation error`);
        }
    }
    memCache.set('schema-errors', null);
}
exports.reportErrors = reportErrors;
function match(schema, input, onError) {
    const res = schema.safeParse(input);
    const { success } = res;
    if (!success) {
        if (onError === 'warn') {
            collectError(schema, res.error);
        }
        if (onError === 'throw') {
            throw res.error;
        }
        return false;
    }
    return true;
}
exports.match = match;
function looseArray(schema, catchCallback) {
    const nullableSchema = schema.nullable().catch(catchCallback
        ? () => {
            catchCallback();
            return null;
        }
        : null);
    const arrayOfNullables = zod_1.z.array(nullableSchema);
    const arrayWithFallback = catchCallback
        ? arrayOfNullables.catch(() => {
            catchCallback();
            return [];
        })
        : arrayOfNullables.catch([]);
    const filteredArray = arrayWithFallback.transform((xs) => xs.filter((x) => !is_1.default.null_(x)));
    return filteredArray;
}
exports.looseArray = looseArray;
function looseRecord(schema, catchCallback) {
    const nullableSchema = schema.nullable().catch(catchCallback
        ? () => {
            catchCallback();
            return null;
        }
        : null);
    const recordOfNullables = zod_1.z.record(nullableSchema);
    const recordWithFallback = catchCallback
        ? recordOfNullables.catch(() => {
            catchCallback();
            return {};
        })
        : recordOfNullables.catch({});
    const filteredRecord = recordWithFallback.transform((rec) => {
        for (const key of Object.keys(rec)) {
            if (is_1.default.null_(rec[key])) {
                delete rec[key];
            }
        }
        return rec;
    });
    return filteredRecord;
}
exports.looseRecord = looseRecord;
//# sourceMappingURL=schema.js.map