import addFormats from 'ajv-formats';
import Ajv2020 from 'ajv/dist/2020';
import draft7MetaSchema from 'ajv/dist/refs/json-schema-draft-07.json';
import { ParseError } from '../types/errors';
import lightdashMetadataSchema from './schemas/lightdashMetadata.json';
import lightdashSchemaV7 from './schemas/lightdashV7.json';
import lightdashSchemaV8 from './schemas/lightdashV8.json';
import lightdashSchemaV9 from './schemas/lightdashV9.json';
import lightdashSchemaV10 from './schemas/lightdashV10.json';
import lightdashSchemaV11 from './schemas/lightdashV11.json';
import lightdashSchemaV12 from './schemas/lightdashV12.json';
import lightdashSchemaV20 from './schemas/lightdashV20.json';
import dbtManifestSchemaV7 from './schemas/manifestV7.json';
import dbtManifestSchemaV8 from './schemas/manifestV8.json';
import dbtManifestSchemaV9 from './schemas/manifestV9.json';
import dbtManifestSchemaV10 from './schemas/manifestV10.json';
import dbtManifestSchemaV11 from './schemas/manifestV11.json';
import dbtManifestSchemaV12 from './schemas/manifestV12.json';
import dbtManifestSchemaV20 from './schemas/manifestV20.json';
// Lazily constructed so that merely importing this module does NOT trigger Ajv
// schema compilation. Ajv validates each added schema against the meta-schema
// using `new Function`, which violates a strict CSP (no `unsafe-eval`). dbt
// manifest validation only runs on the backend/CLI, never in the browser SDK —
// so deferring construction keeps the SDK bundle from compiling validators at
// load time. See issue #21276.
let ajvInstance;
const getAjv = () => {
    if (ajvInstance === undefined) {
        const ajv = new Ajv2020();
        ajv.addMetaSchema(draft7MetaSchema); // add backward compatibility with draft-07
        ajv.addSchema([
            dbtManifestSchemaV7,
            dbtManifestSchemaV8,
            dbtManifestSchemaV9,
            dbtManifestSchemaV10,
            dbtManifestSchemaV11,
            dbtManifestSchemaV12,
            dbtManifestSchemaV20,
            lightdashMetadataSchema,
            lightdashSchemaV7,
            lightdashSchemaV8,
            lightdashSchemaV9,
            lightdashSchemaV10,
            lightdashSchemaV11,
            lightdashSchemaV12,
            lightdashSchemaV20,
        ]);
        addFormats(ajv);
        ajvInstance = ajv;
    }
    return ajvInstance;
};
export class ManifestValidator {
    constructor(manifestVersion) {
        this.isModelValid = (model) => {
            // Seeds are only used as join targets and don't need full model
            // schema validation (which enforces resource_type: "model").
            // They just need valid Lightdash metadata and columns.
            if (model.resource_type === 'seed') {
                return [true, undefined];
            }
            const validator = ManifestValidator.getValidator(`${this.lightdashSchemaId}#/definitions/LightdashCompiledModelNode`);
            return ManifestValidator.isValid(validator, model);
        };
        this.isDbtMetricValid = (metric) => {
            const validator = ManifestValidator.getValidator(`${this.dbtSchemaId}#/definitions/Metric`);
            return ManifestValidator.isValid(validator, metric);
        };
        this.lightdashSchemaId = `https://schemas.lightdash.com/lightdash/${manifestVersion}.json`;
        this.dbtSchemaId = `https://schemas.getdbt.com/dbt/manifest/${manifestVersion}.json`;
    }
}
ManifestValidator.isValid = (validator, data) => {
    const isValid = validator(data);
    if (!isValid) {
        return [false, ManifestValidator.formatAjvErrors(validator)];
    }
    return [true, undefined];
};
ManifestValidator.formatAjvErrors = (validator) => (validator.errors || [])
    .map((err) => `Field at "${err.instancePath}" ${err.message}`)
    .join('\n');
ManifestValidator.getValidator = (schemaRef) => {
    const validator = getAjv().getSchema(schemaRef);
    if (validator === undefined) {
        throw new ParseError(`Could not find schema with reference: ${schemaRef}`);
    }
    return validator;
};
//# sourceMappingURL=validation.js.map