"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.__ΩIPostgresDatabaseAdapterConfig = exports.PostgresDatabaseAdapter = exports.__ΩPostgresDatabaseSession = void 0;
exports.createPostgresDatabase = createPostgresDatabase;
const __ΩConstructorParameters = ['T', 'args', 'new', 'ConstructorParameters', 'l>e"!R!RPde#!Ph"!@2""/#qk#\'QRb!Pde"!p)w$y'];
function __assignType(fn, args) {
    fn.__type = args;
    return fn;
}
/*@ts-ignore*/
var { __ΩClassType } = require('@deepkit/core');
const logger_1 = require("@deepkit/logger");
const orm_1 = require("@deepkit/orm");
const postgres_1 = require("@deepkit/postgres");
const sql_1 = require("@deepkit/sql");
const type_1 = require("@deepkit/type");
const resolver_1 = require("../app/resolver");
const state_1 = require("../app/state");
const common_1 = require("./common");
const __ΩPostgresDatabaseSession = [() => PostgresDatabaseAdapter, () => orm_1.DatabaseSession, 'PostgresDatabaseSession', 'PP7!7"w#y'];
exports.__ΩPostgresDatabaseSession = __ΩPostgresDatabaseSession;
const originalRun = postgres_1.PostgresConnection.prototype.run;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
postgres_1.PostgresConnection.prototype.run = __assignType(async function (sql, params = []) {
    await originalRun.call(this, sql, params);
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    return { affectedRows: this.changes ?? 0, insertId: 0 };
}, ['sql', 'params', () => [], '', 'P&2!"F2">#"/$']);
class PostgresDatabaseAdapter extends postgres_1.PostgresDatabaseAdapter {
    registerTransformations() {
        // any
        this.platform.serializer.deserializeRegistry.register(type_1.ReflectionKind.any, __assignType((_type, state) => {
            state.addSetter(state.accessor);
        }, ['_type', 'state', '', 'P"2!"2""/#']));
        // date string
        this.platform.serializer.deserializeRegistry.addDecorator(__assignType(t => t.typeName === 'DateString', ['t', '', 'P"2!"/"']), __assignType((_type, state) => {
            state.addSetter(`${state.accessor} instanceof Date ? ${state.accessor}.toISOString().substring(0, 10) : ${state.accessor}`);
            state.ended = true;
        }, ['_type', 'state', '', 'P"2!"2""/#']));
        // when Jest/test mocks dates, the Date object checked by Deepkit is not the same as the one created by the mock
        if (process.env.APP_ENV === 'test') {
            const isDate = __assignType((t) => t.kind === type_1.ReflectionKind.class && t.classType.name === 'Date', ['Type', 't', '', 'P"w!2""/#']);
            this.platform.addType(isDate, 'timestamp');
            this.platform.addType(__assignType(t => t.kind === type_1.ReflectionKind.union && t.types.filter(sql_1.isNonUndefined).every(isDate), ['t', '', 'P"2!"/"']), 'timestamp');
        }
    }
}
exports.PostgresDatabaseAdapter = PostgresDatabaseAdapter;
PostgresDatabaseAdapter.__type = [() => postgres_1.PostgresDatabaseAdapter, 'registerTransformations', 'PostgresDatabaseAdapter', 'P7!P"0"5w#'];
const __ΩIPostgresDatabaseAdapterConfig = ['PoolConfig', 'enableLocksTable', 'IPostgresDatabaseAdapterConfig', 'P"w!)4"8Mw#y'];
exports.__ΩIPostgresDatabaseAdapterConfig = __ΩIPostgresDatabaseAdapterConfig;
function createPostgresDatabase(config, entities = []) {
    var _a;
    return _a = class extends common_1.BaseDatabase {
            constructor() {
                const appConfig = (0, resolver_1.getAppConfig)();
                const isProduction = appConfig.APP_ENV === 'production';
                const { enableLocksTable, ...otherConfig } = config;
                const ssl = appConfig.PG_SSL ? { rejectUnauthorized: appConfig.PG_SSL_REJECT_UNAUTHORIZED ?? true } : undefined;
                const adapter = new PostgresDatabaseAdapter({
                    host: appConfig.PG_HOST,
                    port: appConfig.PG_PORT,
                    user: appConfig.PG_USER,
                    password: appConfig.PG_PASSWORD_SECRET,
                    database: appConfig.PG_DATABASE,
                    ssl,
                    max: appConfig.PG_CONNECTION_LIMIT ?? (isProduction ? 10 : 5),
                    idleTimeoutMillis: (appConfig.PG_IDLE_TIMEOUT_SECONDS ?? (isProduction ? 60 : 5)) * 1000,
                    ...otherConfig
                });
                adapter.registerTransformations();
                if (state_1.globalState.additionalEntities) {
                    entities.push(...state_1.globalState.additionalEntities);
                }
                super(adapter, entities);
                if (enableLocksTable) {
                    this.rawExecute(`CREATE TABLE IF NOT EXISTS "_locks" (
                        "key" VARCHAR(255) NOT NULL PRIMARY KEY,
                        "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
                        "lastTouched" TIMESTAMP
                    )`)
                        .then(() => this.rawExecute(`DELETE FROM "_locks" WHERE "lastTouched" < NOW() - INTERVAL '1 hour'`))
                        .catch(__assignType(err => {
                        (0, resolver_1.r)(logger_1.Logger).error(`Could not create _locks table: %s`, err);
                    }, ['err', '', 'P"2!"/"']));
                }
            }
        },
        _a.__type = [() => PostgresDatabaseAdapter, () => common_1.BaseDatabase, 'constructor', () => PostgresDatabaseAdapter, 'PP7!7"P"0#5P7$6"'],
        _a;
}
createPostgresDatabase.__type = [() => __ΩIPostgresDatabaseAdapterConfig, 'config', () => __ΩConstructorParameters, () => orm_1.Database, 1, 'entities', () => [], () => __ΩClassType, () => PostgresDatabaseAdapter, () => common_1.BaseDatabase, 'createPostgresDatabase', 'Pn!2"i$o#".%f2&>\'PP7)7*o("/+'];
//# sourceMappingURL=postgres.js.map