/// <reference types="@cloudflare/workers-types" />
import { D1Orm } from "./database.js";
import type { GenerateQueryOptions } from "./queryBuilder.js";
/**
 * @typeParam T - The type of the model, which will be returned when using methods such as First() or All()
 */
export declare class Model<T extends Record<string, ModelColumn>> {
    #private;
    /**
     * @param options - The options for the model. All parameters except autoIncrement, withRowId, and uniqueKeys are required.
     * @param options.tableName - The name of the table to use.
     * @param options.D1Orm - The D1Orm instance to use - optional. If not set initially, you must use SetOrm() to set before querying.
     * @param options.primaryKeys - The primary key or keys of the table.
     * @param options.autoIncrement - The column to use for auto incrementing. If specified, only one primary key is allowed, and must be of type INTEGER.
     * @param options.uniqueKeys - The unique keys of the table. For example `[ ['id'], ['username', 'discriminator'] ]` would cause ID to be unique, as well as the combination of username and discriminator.
     * @param options.withRowId - Whether or not D1 should generate a `rowid` column automatically. Defaults to false.
     * @param columns - The columns for the model. The keys are the column names, and the values are the column options. See {@link ModelColumn}
     */
    constructor(options: {
        D1Orm?: D1Orm;
        tableName: string;
        primaryKeys: Extract<keyof T, string> | Extract<keyof T, string>[];
        autoIncrement?: Extract<keyof T, string>;
        uniqueKeys?: Extract<keyof T, string>[][];
        withRowId?: boolean;
    }, columns: T);
    readonly tableName: string;
    readonly columns: T;
    readonly primaryKeys: Extract<keyof T, string>[];
    readonly uniqueKeys: Extract<keyof T, string>[][];
    /**
     * @returns The ORM instance that this model is using.
     */
    get D1Orm(): D1Orm;
    /**
     * @param orm The ORM instance to associate this model with.
     */
    SetOrm(orm: D1Orm): this;
    /**
     * @returns A CreateTable definition for the model, which can be used in a CREATE TABLE statement.
     */
    get createTableDefinition(): string;
    /**
     * @param options The options for creating the table. Currently only contains strategy, which is the strategy to use when creating the table.
     * - "default" - The default strategy, which will attempt create the table.
     * - "force" - Drops the table if it exists, then creates it
     * @throws
     * - Throws an error if the table already exists and the strategy is not "force".
     * - Throws an error if the strategy is "alter", as this is not yet implemented
     */
    CreateTable(options?: {
        strategy: "default" | "force";
    }): Promise<D1ExecResult>;
    /**
     * @param silent If true, will ignore the table not existing. If false, will throw an error if the table does not exist.
     */
    DropTable(silent?: boolean): Promise<D1ExecResult>;
    /**
     * @param data The data to insert into the table, as an object with the column names as keys and the values as values.
     */
    InsertOne(data: Partial<InferFromColumns<T>>, orReplace?: boolean): Promise<D1Result<InferFromColumns<T>>>;
    /**
     * @param data The data to insert into the table, as an array of objects with the column names as keys and the values as values.
     */
    InsertMany(data: Partial<InferFromColumns<T>>[], orReplace?: boolean): Promise<D1Result<InferFromColumns<T>>[]>;
    /**
     * @param options The options for the query, see {@link GenerateQueryOptions}
     * @returns Returns the first row that matches the where clause, or null if no rows match.
     */
    First(options: Pick<GenerateQueryOptions<InferFromColumns<T>>, "where">): Promise<InferFromColumns<T> | null>;
    /**
     * @param options The options for the query, see {@link GenerateQueryOptions}
     * @returns Returns all rows that match the where clause.
     */
    All(options: Omit<GenerateQueryOptions<InferFromColumns<T>>, "data" | "upsertOnlyUpdateData">): Promise<D1Result<InferFromColumns<T>>>;
    /**
     * @param options The options for the query, see {@link GenerateQueryOptions}
     */
    Delete(options: Pick<GenerateQueryOptions<InferFromColumns<T>>, "where">): Promise<D1Result<unknown>>;
    /**
     * @param options The options for the query, see {@link GenerateQueryOptions}
     * @throws Throws an error if the data clause is empty.
     */
    Update(options: Pick<GenerateQueryOptions<InferFromColumns<T>>, "where" | "data">): Promise<D1Result<unknown>>;
    /**
     * Upserting is a way to insert a row into the table, or update it if it already exists.
     * This is done by using SQLITE's ON CONFLICT clause. As a result, this method should control the primary key for the insert & where clauses, and should not be used with auto incrementing keys.
     * @param options The options for the query, see {@link GenerateQueryOptions}
     */
    Upsert(options: Pick<GenerateQueryOptions<InferFromColumns<T>>, "where" | "data" | "upsertOnlyUpdateData">): Promise<D1Result<unknown>>;
}
/**
 * The definition of a column in a model.
 * If the `defaultValue` is provided, it should be of the type defined by your `type`. Blobs should be provided as an [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).
 */
export interface ModelColumn {
    type: DataTypes;
    notNull?: boolean;
    defaultValue?: unknown;
}
/**
 * @enum {string} Aliases for DataTypes used in a {@link ModelColumn} definition.
 */
export declare enum DataTypes {
    INTEGER = "integer",
    INT = "integer",
    TEXT = "text",
    STRING = "text",
    VARCHAR = "text",
    CHAR = "text",
    NUMBER = "real",
    NUMERIC = "real",
    REAL = "real",
    BLOB = "blob",
    BOOLEAN = "boolean"
}
/**
 * This is a helper type that allows you to know the JS type of a {@link ModelColumn} type.
 * Should not be used directly, instead see {@link Infer}
 * @internal
 */
export type InferFromColumn<T extends ModelColumn> = T["type"] extends DataTypes.INTEGER ? number : T["type"] extends DataTypes.REAL ? number : T["type"] extends DataTypes.TEXT ? string : T["type"] extends DataTypes.BLOB ? ArrayBuffer : T["type"] extends DataTypes.BOOLEAN ? 1 | 0 : never;
/**
 * This is a helper type that allows you to know the JS type of a Record of {@link ModelColumn}s.
 * Should not be used directly, instead see {@link Infer}
 * @internal
 */
export type InferFromColumns<T extends Record<string, ModelColumn>> = {
    [K in keyof T]: T[K]["notNull"] extends true ? InferFromColumn<T[K]> : InferFromColumn<T[K]> | null;
};
/**
 * Infer is a utility type that allows you to infer the type of a model from the columns.
 * @example
 * ```ts
 * import { Model, DataTypes } from "d1-orm";
 * import type { Infer } from "d1-orm";
 *
 * const users = new Model(
 * 	{
 * 		tableName: "users",
 * 		D1Orm: MyD1OrmInstance,
 * 	},
 * 	{
 * 		name: {
 * 			type: DataTypes.STRING
 * 		},
 * 		age: {
 * 			type: DataTypes.NUMBER
 * 		},
 * 	}
 * );
 *
 * type User = Infer<typeof users>;
 * //type User = {
 * 	//name: string,
 * 	//age: number
 * //}
 * ```
 */
export type Infer<T extends {
    columns: Record<string, ModelColumn>;
}> = InferFromColumns<T["columns"]>;
//# sourceMappingURL=model.d.ts.map