import { ColumnType as ColumnType_2 } from 'kysely';
import { default as default_2 } from 'postgres';
import { Kysely } from 'kysely';
import { Notice } from 'postgres';
import { SSLConfig } from 'pg-connection-string';

export declare enum ActionType {
    NO_ACTION = "NO ACTION",
    RESTRICT = "RESTRICT",
    CASCADE = "CASCADE",
    SET_NULL = "SET NULL",
    SET_DEFAULT = "SET DEFAULT"
}

export declare const AfterDeleteTrigger: (options: Omit<TriggerFunctionOptions, "timing" | "actions">) => ClassDecorator;

export declare const AfterInsertTrigger: (options: Omit<TriggerFunctionOptions, "timing" | "actions">) => ClassDecorator;

export declare const AfterUpdateTrigger: (options: Omit<TriggerFunctionOptions, "timing" | "actions">) => ClassDecorator;

export declare const asHuman: ({ object, type }: SchemaDiff) => string;

export declare const asPostgresConfig: (params: DatabaseConnectionParams) => {
    host: string | undefined;
    port: number | undefined;
    username: string | undefined;
    password: string | undefined;
    database: string | undefined;
    ssl: PostgresSsl | undefined;
};

export declare const asSql: (item: SchemaDiff, options: SchemaDiffToSqlOptions) => string[];

declare class BaseContext {
    databaseName: string;
    schemaName: string;
    overrideTableName: string;
    uuidFunctionFactory: UuidFunctionFactory;
    outputTarget: OutputTarget;
    tables: DatabaseTable[];
    functions: DatabaseFunction[];
    enums: DatabaseEnum[];
    extensions: DatabaseExtension[];
    parameters: DatabaseParameter[];
    overrides: DatabaseOverride[];
    warnings: string[];
    private namingStrategy;
    constructor(options: BaseContextOptions);
    getNameFor(item: NamingItem): string;
    getTableByName(name: string): DatabaseTable | undefined;
    warn(context: string, message: string): void;
    build(): DatabaseSchema;
}

export declare type BaseContextOptions = {
    databaseName?: string;
    schemaName?: string;
    overrideTableName?: string;
    namingStrategy?: 'default' | NamingInterface;
    uuidFunction?: string | UuidFunctionFactory;
    outputTarget?: OutputTarget;
};

export declare const BeforeDeleteTrigger: (options: Omit<TriggerFunctionOptions, "timing" | "actions">) => ClassDecorator;

export declare const BeforeUpdateTrigger: (options: Omit<TriggerFunctionOptions, "timing" | "actions">) => ClassDecorator;

export declare const Check: (options: CheckOptions) => ClassDecorator;

export declare type CheckOptions = {
    name?: string;
    expression: string;
    synchronize?: boolean;
};

declare type ClassBased<T> = {
    object: Function;
} & T;

declare type ColumBasedConstraint = {
    name: string;
    tableName: string;
    columnNames: string[];
};

export declare const Column: (options?: string | ColumnOptions) => PropertyDecorator;

export declare type ColumnBaseOptions = {
    name?: string;
    primary?: boolean;
    type?: ColumnType;
    nullable?: boolean;
    length?: number;
    default?: ColumnValue;
    comment?: string;
    synchronize?: boolean;
    storage?: ColumnStorage;
    identity?: boolean;
    index?: boolean;
    indexName?: string;
    unique?: boolean;
    uniqueConstraintName?: string;
};

export declare type ColumnChanges = {
    nullable?: boolean;
    default?: string;
    comment?: string;
    storage?: ColumnStorage;
};

export declare type ColumnOptions = ColumnBaseOptions & {
    enum?: DatabaseEnum;
    array?: boolean;
};

export declare type ColumnStorage = 'default' | 'external' | 'extended' | 'main';

export declare type ColumnType = 'bigint' | 'boolean' | 'bytea' | 'character' | 'character varying' | 'date' | 'double precision' | '"char"' | 'smallint' | 'integer' | 'jsonb' | 'polygon' | 'text' | 'time' | 'time with time zone' | 'time without time zone' | 'timestamp' | 'timestamp with time zone' | 'timestamp without time zone' | 'uuid' | 'vector' | 'enum' | 'serial' | 'real';

export declare type ColumnValue = null | boolean | string | number | Array<unknown> | object | Date | (() => string);

export declare type CompareFunction<T> = (source: T, target: T) => SchemaDiff[];

export declare type Comparer<T> = {
    onMissing: (source: T) => SchemaDiff[];
    onExtra: (target: T) => SchemaDiff[];
    onCompare: CompareFunction<T>;
    /** if two items have the same key, they are considered identical and can be renamed via `onRename` */
    getRenameKey?: (item: T) => string;
    onRename?: (source: T, target: T) => SchemaDiff[];
};

export declare const ConfigurationParameter: (options: ConfigurationParameterOptions) => ClassDecorator;

export declare type ConfigurationParameterOptions = {
    name: string;
    value: ColumnValue;
    scope: ParameterScope;
    synchronize?: boolean;
};

export declare enum ConstraintType {
    PRIMARY_KEY = "primary-key",
    FOREIGN_KEY = "foreign-key",
    UNIQUE = "unique",
    CHECK = "check"
}

export declare const CreateDateColumn: (options?: ColumnOptions) => PropertyDecorator;

export declare const createPostgres: (options?: DatabasePostgresOptions) => default_2.Sql<{}>;

export declare const Database: (options: DatabaseOptions) => ClassDecorator;

export declare type DatabaseCheckConstraint = {
    type: ConstraintType.CHECK;
    name: string;
    tableName: string;
    expression: string;
    synchronize: boolean;
};

export declare type DatabaseClient = Kysely<PostgresDB>;

export declare type DatabaseColumn = {
    primary: boolean;
    name: string;
    tableName: string;
    comment?: string;
    type: ColumnType;
    nullable: boolean;
    isArray: boolean;
    synchronize: boolean;
    default?: string;
    length?: number;
    storage?: ColumnStorage;
    identity?: boolean;
    enumName?: string;
    numericPrecision?: number;
    numericScale?: number;
};

export declare type DatabaseConnectionParams = DatabaseConnectionURL | DatabaseConnectionParts;

declare type DatabaseConnectionParams_2 = DatabaseConnectionURL_2 | DatabaseConnectionParts_2;

export declare type DatabaseConnectionParts = {
    connectionType: 'parts';
    host: string;
    port: number;
    username: string;
    password: string;
    database: string;
    ssl?: DatabaseSslMode;
};

declare type DatabaseConnectionParts_2 = {
    connectionType: 'parts';
    host: string;
    port: number;
    username: string;
    password: string;
    database: string;
    ssl?: DatabaseSslMode_2;
};

export declare type DatabaseConnectionURL = {
    connectionType: 'url';
    url: string;
};

declare type DatabaseConnectionURL_2 = {
    connectionType: 'url';
    url: string;
};

export declare type DatabaseConstraint = DatabasePrimaryKeyConstraint | DatabaseForeignKeyConstraint | DatabaseUniqueConstraint | DatabaseCheckConstraint;

export declare type DatabaseEnum = {
    name: string;
    values: string[];
    synchronize: boolean;
};

export declare type DatabaseExtension = {
    name: string;
    synchronize: boolean;
};

export declare type DatabaseForeignKeyConstraint = ColumBasedConstraint & {
    type: ConstraintType.FOREIGN_KEY;
    referenceTableName: string;
    referenceColumnNames: string[];
    onUpdate?: ActionType;
    onDelete?: ActionType;
    /** table create sql should not inline this constraint */
    deferred?: boolean;
    synchronize: boolean;
};

export declare type DatabaseFunction = {
    name: string;
    expression: string;
    synchronize: boolean;
    override?: DatabaseOverride;
};

export declare type DatabaseIndex = {
    name: string;
    tableName: string;
    columnNames?: string[];
    expression?: string;
    unique: boolean;
    using?: string;
    with?: string;
    where?: string;
    override?: DatabaseOverride;
    synchronize: boolean;
};

export declare type DatabaseOptions = {
    name?: string;
    synchronize?: boolean;
};

export declare type DatabaseOverride = {
    name: string;
    value: {
        name: string;
        type: OverrideType;
        sql: string;
    };
    synchronize: boolean;
};

export declare type DatabaseParameter = {
    name: string;
    databaseName: string;
    value: string | number | null | undefined;
    scope: ParameterScope;
    synchronize: boolean;
};

export declare type DatabasePostgresOptions = {
    connection?: DatabaseConnectionParams;
    maxConnections?: number;
    timeZone?: string;
    convertToJsDate?: boolean;
    convertBigIntToNumber?: boolean;
    onNotice?: (notice: Notice) => void;
    onClose?: (connectionId: number) => void;
};

export declare type DatabasePrimaryKeyConstraint = ColumBasedConstraint & {
    type: ConstraintType.PRIMARY_KEY;
    synchronize: boolean;
};

export declare type DatabaseSchema = {
    databaseName: string;
    schemaName: string;
    functions: DatabaseFunction[];
    enums: DatabaseEnum[];
    tables: DatabaseTable[];
    extensions: DatabaseExtension[];
    parameters: DatabaseParameter[];
    overrides: DatabaseOverride[];
    warnings: string[];
};

export declare enum DatabaseSslMode {
    Disable = "disable",
    Allow = "allow",
    Prefer = "prefer",
    Require = "require",
    VerifyFull = "verify-full"
}

declare enum DatabaseSslMode_2 {
    Disable = 'disable',
    Allow = 'allow',
    Prefer = 'prefer',
    Require = 'require',
    VerifyFull = 'verify-full',
}

export declare type DatabaseTable = {
    name: string;
    columns: DatabaseColumn[];
    indexes: DatabaseIndex[];
    constraints: DatabaseConstraint[];
    triggers: DatabaseTrigger[];
    synchronize: boolean;
};

export declare type DatabaseTrigger = {
    name: string;
    tableName: string;
    timing: TriggerTiming;
    actions: TriggerAction[];
    scope: TriggerScope;
    referencingNewTableAs?: string;
    referencingOldTableAs?: string;
    when?: string;
    functionName: string;
    override?: DatabaseOverride;
    synchronize: boolean;
};

export declare type DatabaseUniqueConstraint = ColumBasedConstraint & {
    type: ConstraintType.UNIQUE;
    synchronize: boolean;
};

export declare class DefaultNamingStrategy {
    getName(item: NamingItem): string;
}

declare const defaultUuidFactory: ({ db, major }: {
    db: string;
    major: string;
}) => UuidFunctionFactory_2;

export declare const DeleteDateColumn: (options?: ColumnOptions) => PropertyDecorator;

export declare type EnumOptions = {
    name: string;
    values: string[];
    synchronize?: boolean;
};

export declare const Extension: (options: string | ExtensionOptions) => ClassDecorator;

export declare type ExtensionOptions = {
    name: string;
    synchronize?: boolean;
};

export declare const Extensions: (options: Array<string | ExtensionsOptions>) => ClassDecorator;

export declare type ExtensionsOptions = {
    name: string;
    synchronize?: boolean;
};

export declare type ForeignKeyAction = 'CASCADE' | 'SET NULL' | 'SET DEFAULT' | 'RESTRICT' | 'NO ACTION';

export declare const ForeignKeyColumn: (target: () => Function, options?: ForeignKeyColumnOptions) => PropertyDecorator;

export declare type ForeignKeyColumnOptions = ColumnBaseOptions & {
    onUpdate?: ForeignKeyAction;
    onDelete?: ForeignKeyAction;
    constraintName?: string;
};

export declare const ForeignKeyConstraint: (options: ForeignKeyConstraintOptions) => ClassDecorator;

export declare type ForeignKeyConstraintOptions = {
    name?: string;
    index?: boolean;
    indexName?: string;
    columns: string[];
    referenceTable: () => Function;
    referenceColumns?: string[];
    onUpdate?: ForeignKeyAction;
    onDelete?: ForeignKeyAction;
    synchronize?: boolean;
};

export declare type FunctionOptions = {
    name: string;
    arguments?: string[];
    returnType: ColumnType | string;
    language?: 'SQL' | 'PLPGSQL';
    behavior?: 'immutable' | 'stable' | 'volatile';
    parallel?: 'safe' | 'unsafe' | 'restricted';
    strict?: boolean;
    synchronize?: boolean;
} & ({
    body: string;
} | {
    return: string;
});

export declare type GenerateColumnOptions = Omit<ColumnOptions, 'type'> & {
    strategy?: GeneratedColumnStrategy;
};

export declare type Generated<T> = T extends ColumnType_2<infer S, infer I, infer U> ? ColumnType_2<S, I | undefined, U> : ColumnType_2<T, T | undefined, T>;

export declare const GeneratedColumn: ({ strategy, ...options }: GenerateColumnOptions) => PropertyDecorator;

export declare type GeneratedColumnStrategy = 'uuid' | 'uuid-v4' | 'uuid-v7' | 'identity';

export declare type IgnoreOptions = boolean | {
    ignoreExtra?: boolean;
    ignoreMissing?: boolean;
};

export declare const Index: (options?: string | IndexOptions) => ClassDecorator;

export declare type IndexOptions = {
    name?: string;
    unique?: boolean;
    expression?: string;
    using?: string;
    with?: string;
    where?: string;
    columns?: string[];
    synchronize?: boolean;
};

export declare type Int8 = ColumnType_2<number>;

declare type InternalColumnOptions = ColumnOptions & {
    strategy?: GeneratedColumnStrategy;
};

export declare const isPostgresSsl: (ssl?: string | boolean | object) => ssl is PostgresSsl;

export declare class Migrator {
    #private;
    constructor(options: {
        connectionParams: DatabaseConnectionParams_2;
        allowUnorderedMigrations: boolean;
        migrationFolder: string;
        uuidFactory?: typeof defaultUuidFactory;
    });
    getDatabase(): Kysely<unknown>;
    runMigrations(): Promise<void>;
    revert(migrationsDistFolder: string): Promise<void>;
    generate({ dist, targetPath, withComments }: {
        dist: string;
        targetPath: string;
        withComments: boolean;
    }): Promise<void>;
    create(path: string, up: string[], down: string[]): void;
    destroy(): Promise<void>;
}

export declare interface NamingInterface {
    getName(item: NamingItem): string;
}

export declare type NamingItem = {
    type: 'database';
    name: string;
} | {
    type: 'table';
    name: string;
} | {
    type: 'column';
    name: string;
} | {
    type: 'primaryKey';
    tableName: string;
    columnNames: string[];
} | {
    type: 'foreignKey';
    tableName: string;
    columnNames: string[];
    referenceTableName: string;
    referenceColumnNames: string[];
} | {
    type: 'check';
    tableName: string;
    expression: string;
} | {
    type: 'unique';
    tableName: string;
    columnNames: string[];
} | {
    type: 'index';
    tableName: string;
    columnNames?: string[];
    expression?: string;
    where?: string;
} | {
    type: 'trigger';
    tableName: string;
    functionName: string;
    actions: TriggerAction[];
    scope: TriggerScope;
    timing: TriggerTiming;
    columnNames?: string[];
    expression?: string;
    where?: string;
};

export declare type OutputTarget = 'sql' | 'javascript';

export declare type OverrideType = 'function' | 'index' | 'trigger';

export declare type ParameterScope = 'database' | 'user';

export declare type PostgresDB = {
    pg_am: {
        oid: number;
        amname: string;
        amhandler: string;
        amtype: string;
    };
    pg_attribute: {
        attrelid: number;
        attname: string;
        attnum: number;
        atttypeid: number;
        attstattarget: number;
        attstatarget: number;
        aanum: number;
    };
    pg_class: {
        oid: number;
        relname: string;
        relkind: string;
        relnamespace: string;
        reltype: string;
        relowner: string;
        relam: string;
        relfilenode: string;
        reltablespace: string;
        relpages: number;
        reltuples: number;
        relallvisible: number;
        reltoastrelid: string;
        relhasindex: PostgresYesOrNo;
        relisshared: PostgresYesOrNo;
        relpersistence: string;
    };
    pg_constraint: {
        oid: number;
        conname: string;
        conrelid: string;
        contype: string;
        connamespace: string;
        conkey: number[];
        confkey: number[];
        confrelid: string;
        confupdtype: string;
        confdeltype: string;
        confmatchtype: number;
        condeferrable: PostgresYesOrNo;
        condeferred: PostgresYesOrNo;
        convalidated: PostgresYesOrNo;
        conindid: number;
    };
    pg_description: {
        objoid: string;
        classoid: string;
        objsubid: number;
        description: string;
    };
    pg_trigger: {
        oid: string;
        tgisinternal: boolean;
        tginitdeferred: boolean;
        tgdeferrable: boolean;
        tgrelid: string;
        tgfoid: string;
        tgname: string;
        tgenabled: string;
        tgtype: number;
        tgconstraint: string;
        tgdeferred: boolean;
        tgargs: Buffer;
        tgoldtable: string;
        tgnewtable: string;
        tgqual: string;
    };
    'pg_catalog.pg_extension': {
        oid: string;
        extname: string;
        extowner: string;
        extnamespace: string;
        extrelocatable: boolean;
        extversion: string;
        extconfig: string[];
        extcondition: string[];
    };
    pg_enum: {
        oid: string;
        enumtypid: string;
        enumsortorder: number;
        enumlabel: string;
    };
    pg_index: {
        indexrelid: string;
        indrelid: string;
        indisready: boolean;
        indexprs: string | null;
        indpred: string | null;
        indkey: number[];
        indisprimary: boolean;
        indisunique: boolean;
    };
    pg_indexes: {
        schemaname: string;
        tablename: string;
        indexname: string;
        tablespace: string | null;
        indexrelid: string;
        indexdef: string;
    };
    pg_namespace: {
        oid: number;
        nspname: string;
        nspowner: number;
        nspacl: string[];
    };
    pg_type: {
        oid: string;
        typname: string;
        typnamespace: string;
        typowner: string;
        typtype: string;
        typcategory: string;
        typarray: string;
    };
    pg_depend: {
        objid: string;
        deptype: string;
    };
    pg_proc: {
        oid: string;
        proname: string;
        pronamespace: string;
        prokind: string;
    };
    pg_settings: {
        name: string;
        setting: string;
        unit: string | null;
        category: string;
        short_desc: string | null;
        extra_desc: string | null;
        context: string;
        vartype: string;
        source: string;
        min_val: string | null;
        max_val: string | null;
        enumvals: string[] | null;
        boot_val: string | null;
        reset_val: string | null;
        sourcefile: string | null;
        sourceline: number | null;
        pending_restart: PostgresYesOrNo;
    };
    'information_schema.tables': {
        table_catalog: string;
        table_schema: string;
        table_name: string;
        table_type: 'VIEW' | 'BASE TABLE' | string;
        is_insertable_info: PostgresYesOrNo;
        is_typed: PostgresYesOrNo;
        commit_action: string | null;
    };
    'information_schema.columns': {
        table_catalog: string;
        table_schema: string;
        table_name: string;
        column_name: string;
        ordinal_position: number;
        column_default: string | null;
        is_nullable: PostgresYesOrNo;
        data_type: string;
        dtd_identifier: string;
        character_maximum_length: number | null;
        character_octet_length: number | null;
        numeric_precision: number | null;
        numeric_precision_radix: number | null;
        numeric_scale: number | null;
        datetime_precision: number | null;
        interval_type: string | null;
        interval_precision: number | null;
        udt_catalog: string;
        udt_schema: string;
        udt_name: string;
        maximum_cardinality: number | null;
        is_updatable: PostgresYesOrNo;
    };
    'information_schema.element_types': {
        object_catalog: string;
        object_schema: string;
        object_name: string;
        object_type: string;
        collection_type_identifier: string;
        data_type: string;
    };
    'information_schema.routines': {
        specific_catalog: string;
        specific_schema: string;
        specific_name: string;
        routine_catalog: string;
        routine_schema: string;
        routine_name: string;
        routine_type: string;
        data_type: string;
        type_udt_catalog: string;
        type_udt_schema: string;
        type_udt_name: string;
        dtd_identifier: string;
        routine_body: string;
        routine_definition: string;
        external_name: string;
        external_language: string;
        is_deterministic: PostgresYesOrNo;
        security_type: string;
    };
};

export declare type PostgresSsl = 'require' | 'allow' | 'prefer' | 'verify-full' | boolean | SSLConfig;

declare type PostgresYesOrNo = 'YES' | 'NO';

export declare const PrimaryColumn: (options?: Omit<ColumnOptions, "primary">) => PropertyDecorator;

export declare const PrimaryGeneratedColumn: (options?: Omit<GenerateColumnOptions, "primary">) => PropertyDecorator;

export declare type Processor = (ctx: ProcessorContext, items: RegisterItem[]) => void;

declare class ProcessorContext extends BaseContext {
    options: SchemaFromCodeOptions;
    constructor(options: SchemaFromCodeOptions);
    classToTable: WeakMap<Function, DatabaseTable>;
    tableToMetadata: WeakMap<DatabaseTable, TableMetadata>;
    getTableByObject(object: Function): DatabaseTable | undefined;
    getTableMetadata(table: DatabaseTable): TableMetadata;
    addTable(table: DatabaseTable, options: TableOptions, object: Function): void;
    getColumnByObjectAndPropertyName(object: object, propertyName: string | symbol): {
        table?: DatabaseTable;
        column?: DatabaseColumn;
    };
    addColumn(table: DatabaseTable, input: DatabaseColumn, propertyName: string | symbol): void;
    onMissingTable(context: string, name: string): never;
    onMissingTable(context: string, object: object, propertyName?: symbol | string): never;
    onMissingColumn(context: string, name: string): never;
    onMissingColumn(context: string, object: object, propertyName?: symbol | string): never;
}

declare type PropertyBased<T> = {
    object: object;
    propertyName: string | symbol;
} & T;

export declare type Reader = (ctx: ReaderContext, db: DatabaseClient) => Promise<void>;

declare class ReaderContext extends BaseContext {
    options: SchemaFromDatabaseOptions;
    constructor(options: SchemaFromDatabaseOptions);
}

export declare enum Reason {
    MissingInSource = "missing in source",
    MissingInTarget = "missing in target",
    Rename = "name has changed"
}

export declare const registerEnum: (options: EnumOptions) => DatabaseEnum;

export declare const registerFunction: (options: FunctionOptions) => DatabaseFunction;

declare type RegisterItem = {
    type: 'database';
    item: ClassBased<{
        options: DatabaseOptions;
    }>;
} | {
    type: 'table';
    item: ClassBased<{
        options: TableOptions;
    }>;
} | {
    type: 'index';
    item: ClassBased<{
        options: IndexOptions;
    }>;
} | {
    type: 'uniqueConstraint';
    item: ClassBased<{
        options: UniqueOptions;
    }>;
} | {
    type: 'checkConstraint';
    item: ClassBased<{
        options: CheckOptions;
    }>;
} | {
    type: 'column';
    item: PropertyBased<{
        options: InternalColumnOptions;
    }>;
} | {
    type: 'function';
    item: DatabaseFunction;
} | {
    type: 'enum';
    item: DatabaseEnum;
} | {
    type: 'trigger';
    item: ClassBased<{
        options: TriggerOptions;
    }>;
} | {
    type: 'extension';
    item: ClassBased<{
        options: ExtensionOptions;
    }>;
} | {
    type: 'configurationParameter';
    item: ClassBased<{
        options: ConfigurationParameterOptions;
    }>;
} | {
    type: 'foreignKeyColumn';
    item: PropertyBased<{
        options: ForeignKeyColumnOptions;
        target: () => Function;
    }>;
} | {
    type: 'foreignKeyConstraint';
    item: ClassBased<{
        options: ForeignKeyConstraintOptions;
    }>;
};

export declare type SchemaDiff = {
    reason: string;
} & SchemaItem;

/**
 * Compute the difference between two database schemas
 */
export declare const schemaDiff: (source: DatabaseSchema, target: DatabaseSchema, options?: SchemaDiffOptions) => SchemaDiffResult;

export declare type SchemaDiffOptions = BaseContextOptions & {
    tables?: IgnoreOptions;
    columns?: IgnoreOptions;
    indexes?: IgnoreOptions;
    triggers?: IgnoreOptions;
    constraints?: IgnoreOptions;
    functions?: IgnoreOptions;
    enums?: IgnoreOptions;
    extensions?: IgnoreOptions;
    parameters?: IgnoreOptions;
    overrides?: IgnoreOptions;
};

export declare type SchemaDiffResult = {
    items: SchemaDiff[];
    asSql: (options?: SchemaDiffToSqlOptions) => string[];
    asHuman: () => string[];
};

/**
 * Convert schema diff into human readable statements
 */
export declare const schemaDiffToHuman: (items: SchemaDiff[]) => string[];

/**
 * Convert schema diffs into SQL statements
 */
export declare const schemaDiffToSql: (items: SchemaDiff[], options?: SchemaDiffToSqlOptions) => string[];

export declare type SchemaDiffToSqlOptions = BaseContextOptions & {
    comments?: boolean;
};

/**
 * Load schema from code (decorators, etc)
 */
export declare const schemaFromCode: (options?: SchemaFromCodeOptions) => DatabaseSchema;

export declare type SchemaFromCodeOptions = BaseContextOptions & {
    /** automatically create indexes on foreign key columns */
    createForeignKeyIndexes?: boolean;
    reset?: boolean;
    functions?: boolean;
    extensions?: boolean;
    parameters?: boolean;
    overrides?: boolean;
};

/**
 * Load schema from a database url
 */
export declare const schemaFromDatabase: (options?: SchemaFromDatabaseOptions) => Promise<DatabaseSchema>;

export declare type SchemaFromDatabaseOptions = BaseContextOptions & DatabasePostgresOptions;

export declare type SchemaItem = {
    type: 'ExtensionCreate';
    object: DatabaseExtension;
} | {
    type: 'ExtensionDrop';
    object: DatabaseExtension;
} | {
    type: 'FunctionCreate';
    object: DatabaseFunction;
} | {
    type: 'FunctionDrop';
    object: DatabaseFunction;
} | {
    type: 'TableCreate';
    object: DatabaseTable;
} | {
    type: 'TableDrop';
    object: DatabaseTable;
} | {
    type: 'ColumnAdd';
    object: DatabaseColumn;
} | {
    type: 'ColumnRename';
    object: {
        old: DatabaseColumn;
        new: DatabaseColumn;
    };
} | {
    type: 'ColumnAlter';
    object: {
        old: DatabaseColumn;
        new: DatabaseColumn;
        changes: ColumnChanges;
    };
} | {
    type: 'ColumnDrop';
    object: DatabaseColumn;
} | {
    type: 'ConstraintAdd';
    object: DatabaseConstraint;
} | {
    type: 'ConstraintRename';
    object: {
        old: DatabaseConstraint;
        new: DatabaseConstraint;
    };
} | {
    type: 'ConstraintDrop';
    object: DatabaseConstraint;
} | {
    type: 'IndexCreate';
    object: DatabaseIndex;
} | {
    type: 'IndexRename';
    object: {
        old: DatabaseIndex;
        new: DatabaseIndex;
    };
} | {
    type: 'IndexDrop';
    object: DatabaseIndex;
} | {
    type: 'TriggerCreate';
    object: DatabaseTrigger;
} | {
    type: 'TriggerDrop';
    object: DatabaseTrigger;
} | {
    type: 'ParameterSet';
    object: DatabaseParameter;
} | {
    type: 'ParameterReset';
    object: DatabaseParameter;
} | {
    type: 'EnumCreate';
    object: DatabaseEnum;
} | {
    type: 'EnumDrop';
    object: DatabaseEnum;
} | {
    type: 'OverrideCreate';
    object: DatabaseOverride;
} | {
    type: 'OverrideUpdate';
    object: DatabaseOverride;
} | {
    type: 'OverrideDrop';
    object: DatabaseOverride;
};

/** Table comments here */
export declare const Table: (options?: string | TableOptions) => ClassDecorator;

declare type TableMetadata = {
    options: TableOptions;
    object: Function;
    methodToColumn: Map<string | symbol, DatabaseColumn>;
};

export declare type TableOptions = {
    name?: string;
    primaryConstraintName?: string;
    synchronize?: boolean;
};

export declare type Timestamp = ColumnType_2<Date, Date | string, Date | string>;

export declare const Trigger: (options: TriggerOptions) => ClassDecorator;

export declare type TriggerAction = 'insert' | 'update' | 'delete' | 'truncate';

export declare const TriggerFunction: (options: TriggerFunctionOptions) => ClassDecorator;

export declare type TriggerFunctionOptions = Omit<TriggerOptions, 'functionName'> & {
    function: DatabaseFunction;
};

export declare type TriggerOptions = {
    name?: string;
    timing: TriggerTiming;
    actions: TriggerAction[];
    scope: TriggerScope;
    functionName: string;
    referencingNewTableAs?: string;
    referencingOldTableAs?: string;
    when?: string;
    synchronize?: boolean;
};

export declare type TriggerScope = 'row' | 'statement';

export declare type TriggerTiming = 'before' | 'after' | 'instead of';

export declare const Unique: (options: UniqueOptions) => ClassDecorator;

export declare type UniqueOptions = {
    name?: string;
    columns: string[];
    synchronize?: boolean;
};

export declare const UpdateDateColumn: (options?: ColumnOptions) => PropertyDecorator;

export declare type UuidFunctionFactory = (version?: 4 | 7) => string;

declare type UuidFunctionFactory_2 = (version?: 4 | 7) => string;

export { }
