"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.entity = void 0;
const reflection_class_1 = require("./reflection-class");
const metadata_store_1 = require("./metadata-store");
exports.entity = function entityDecorator(target) {
    applyClassOptions(target, {});
    return target;
};
Object.defineProperty(exports.entity, 'name', {
    configurable: true,
    value(name) {
        return createEntityDecorator({ collectionName: name });
    }
});
Object.defineProperty(exports.entity, 'index', {
    configurable: true,
    value(names, options = {}) {
        return createEntityDecorator({ indexes: [{ names: [...names], options }] });
    }
});
Object.defineProperty(exports.entity, 'excludeMigration', {
    configurable: true,
    value() {
        return createEntityDecorator({ excludeMigration: true });
    }
});
Object.defineProperty(exports.entity, 'generated', {
    configurable: true,
    value(expression, options = {}) {
        const generated = normalizeGeneratedColumnOptions(expression, options.storage);
        return (target, propertyKey) => {
            if (typeof propertyKey !== 'string')
                throw new Error('Generated columns require a string property name');
            applyClassOptions(target.constructor, { generatedColumns: { [propertyKey]: generated } });
        };
    }
});
function ensureClassOptions(target) {
    let options = metadata_store_1.classOptions.get(target);
    if (!options) {
        options = {};
        metadata_store_1.classOptions.set(target, options);
    }
    return options;
}
function createEntityDecorator(options) {
    const decorator = function compatibleEntityDecorator(target) {
        applyClassOptions(target, options);
        return target;
    };
    Object.defineProperty(decorator, 'index', {
        configurable: true,
        value(names, indexOptions = {}) {
            return createEntityDecorator({
                ...options,
                indexes: [...(options.indexes ?? []), { names: [...names], options: indexOptions }]
            });
        }
    });
    Object.defineProperty(decorator, 'excludeMigration', {
        configurable: true,
        value() {
            return createEntityDecorator({
                ...options,
                excludeMigration: true
            });
        }
    });
    return decorator;
}
function applyClassOptions(target, incoming) {
    const options = ensureClassOptions(target);
    if (incoming.collectionName)
        options.collectionName = incoming.collectionName;
    if (incoming.indexes?.length)
        options.indexes = [...(options.indexes ?? []), ...incoming.indexes];
    if (incoming.excludeMigration)
        options.excludeMigration = true;
    if (incoming.generatedColumns)
        options.generatedColumns = { ...options.generatedColumns, ...incoming.generatedColumns };
    const metadata = (0, reflection_class_1.readClassMetadata)(target);
    if (metadata)
        (0, metadata_store_1.applyMetadataOptions)(metadata, options);
}
function normalizeGeneratedColumnOptions(expression, storage) {
    if (!expression.trim())
        throw new Error('Generated column expressions must not be empty');
    if (storage !== undefined && storage !== 'virtual' && storage !== 'stored') {
        throw new Error(`Unsupported generated column storage ${storage}`);
    }
    return { expression, storage: storage ?? 'virtual' };
}
//# sourceMappingURL=entity.js.map