hysteria-orm 10.5.0 → 10.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -1169,37 +1169,6 @@ declare class RawNode extends QueryNode {
1169
1169
  constructor(value: string);
1170
1170
  }
1171
1171
 
1172
- type ConstraintType = "primary_key" | "foreign_key" | "unique" | "not_null" | "null" | "default";
1173
- declare class ConstraintNode extends QueryNode {
1174
- constraintType: ConstraintType;
1175
- columns?: (string | (() => string))[];
1176
- references?: {
1177
- table: string;
1178
- columns: (string | (() => string))[];
1179
- };
1180
- constraintName?: string;
1181
- onDelete?: "cascade" | "restrict" | "set null" | "no action";
1182
- onUpdate?: "cascade" | "restrict" | "set null" | "no action";
1183
- defaultValue?: string | RawNode | undefined;
1184
- checkExpression?: string;
1185
- chainsWith: string;
1186
- canKeywordBeSeenMultipleTimes: boolean;
1187
- folder: string;
1188
- file: string;
1189
- constructor(constraintType: ConstraintType, args?: {
1190
- columns?: string[];
1191
- references?: {
1192
- table: string;
1193
- columns: string[];
1194
- };
1195
- constraintName?: string;
1196
- onDelete?: "cascade" | "restrict" | "set null" | "no action";
1197
- onUpdate?: "cascade" | "restrict" | "set null" | "no action";
1198
- defaultValue?: string | RawNode | undefined;
1199
- checkExpression?: string;
1200
- }, isRawValue?: boolean);
1201
- }
1202
-
1203
1172
  type Sqlite3ConnectionOptions = {
1204
1173
  mode: number;
1205
1174
  };
@@ -1417,6 +1386,12 @@ type RawQueryOptions = {
1417
1386
  replicationMode?: ReplicationType;
1418
1387
  };
1419
1388
 
1389
+ declare abstract class BaseBuilder {
1390
+ protected nodes: QueryNode[];
1391
+ constructor(nodes: QueryNode[]);
1392
+ getNodes(): QueryNode[];
1393
+ }
1394
+
1420
1395
  declare class ColumnTypeNode extends QueryNode {
1421
1396
  column: string | (() => string);
1422
1397
  dataType: string;
@@ -1442,45 +1417,6 @@ declare class ColumnTypeNode extends QueryNode {
1442
1417
  });
1443
1418
  }
1444
1419
 
1445
- type LockType = "for_update" | "for_share" | "for_no_key_update" | "for_key_share";
1446
- declare class LockNode extends QueryNode {
1447
- lockType: LockType;
1448
- skipLocked: boolean;
1449
- noWait: boolean;
1450
- chainsWith: string;
1451
- canKeywordBeSeenMultipleTimes: boolean;
1452
- folder: string;
1453
- file: string;
1454
- constructor(lockType: LockType, skipLocked?: boolean, noWait?: boolean);
1455
- }
1456
-
1457
- declare class UnionNode extends QueryNode {
1458
- query: QueryNode | QueryNode[] | string;
1459
- isAll: boolean;
1460
- chainsWith: string;
1461
- canKeywordBeSeenMultipleTimes: boolean;
1462
- folder: string;
1463
- file: string;
1464
- constructor(query: QueryNode | QueryNode[] | string, isAll?: boolean);
1465
- }
1466
-
1467
- declare class WithNode extends QueryNode {
1468
- alias: string;
1469
- body: QueryNode | QueryNode[];
1470
- clause: string;
1471
- chainsWith: string;
1472
- canKeywordBeSeenMultipleTimes: boolean;
1473
- folder: string;
1474
- file: string;
1475
- constructor(clause: string, alias: string, body: QueryNode | QueryNode[]);
1476
- }
1477
-
1478
- declare abstract class BaseBuilder {
1479
- protected nodes: QueryNode[];
1480
- constructor(nodes: QueryNode[]);
1481
- getNodes(): QueryNode[];
1482
- }
1483
-
1484
1420
  declare class ConstraintBuilder extends BaseBuilder {
1485
1421
  private readonly columnNode;
1486
1422
  private readonly tableName?;
@@ -1858,6 +1794,70 @@ declare class CreateTableBuilder extends BaseBuilder {
1858
1794
  getNamedConstraints(): QueryNode[];
1859
1795
  }
1860
1796
 
1797
+ type ConstraintType = "primary_key" | "foreign_key" | "unique" | "not_null" | "null" | "default";
1798
+ declare class ConstraintNode extends QueryNode {
1799
+ constraintType: ConstraintType;
1800
+ columns?: (string | (() => string))[];
1801
+ references?: {
1802
+ table: string;
1803
+ columns: (string | (() => string))[];
1804
+ };
1805
+ constraintName?: string;
1806
+ onDelete?: "cascade" | "restrict" | "set null" | "no action";
1807
+ onUpdate?: "cascade" | "restrict" | "set null" | "no action";
1808
+ defaultValue?: string | RawNode | undefined;
1809
+ checkExpression?: string;
1810
+ chainsWith: string;
1811
+ canKeywordBeSeenMultipleTimes: boolean;
1812
+ folder: string;
1813
+ file: string;
1814
+ constructor(constraintType: ConstraintType, args?: {
1815
+ columns?: string[];
1816
+ references?: {
1817
+ table: string;
1818
+ columns: string[];
1819
+ };
1820
+ constraintName?: string;
1821
+ onDelete?: "cascade" | "restrict" | "set null" | "no action";
1822
+ onUpdate?: "cascade" | "restrict" | "set null" | "no action";
1823
+ defaultValue?: string | RawNode | undefined;
1824
+ checkExpression?: string;
1825
+ }, isRawValue?: boolean);
1826
+ }
1827
+
1828
+ type LockType = "for_update" | "for_share" | "for_no_key_update" | "for_key_share";
1829
+ declare class LockNode extends QueryNode {
1830
+ lockType: LockType;
1831
+ skipLocked: boolean;
1832
+ noWait: boolean;
1833
+ chainsWith: string;
1834
+ canKeywordBeSeenMultipleTimes: boolean;
1835
+ folder: string;
1836
+ file: string;
1837
+ constructor(lockType: LockType, skipLocked?: boolean, noWait?: boolean);
1838
+ }
1839
+
1840
+ declare class UnionNode extends QueryNode {
1841
+ query: QueryNode | QueryNode[] | string;
1842
+ isAll: boolean;
1843
+ chainsWith: string;
1844
+ canKeywordBeSeenMultipleTimes: boolean;
1845
+ folder: string;
1846
+ file: string;
1847
+ constructor(query: QueryNode | QueryNode[] | string, isAll?: boolean);
1848
+ }
1849
+
1850
+ declare class WithNode extends QueryNode {
1851
+ alias: string;
1852
+ body: QueryNode | QueryNode[];
1853
+ clause: string;
1854
+ chainsWith: string;
1855
+ canKeywordBeSeenMultipleTimes: boolean;
1856
+ folder: string;
1857
+ file: string;
1858
+ constructor(clause: string, alias: string, body: QueryNode | QueryNode[]);
1859
+ }
1860
+
1861
1861
  declare class AlterTableBuilder extends BaseBuilder {
1862
1862
  private table;
1863
1863
  private sqlType;
@@ -1959,105 +1959,146 @@ declare class AlterTableBuilder extends BaseBuilder {
1959
1959
  dropPrimaryKey(table?: string): void;
1960
1960
  }
1961
1961
 
1962
- declare class Schema {
1963
- queryStatements: string[];
1964
- sqlType: SqlDataSourceType;
1965
- constructor(sqlType?: SqlDataSourceType);
1962
+ /**
1963
+ * @description SchemaBuilder class for building and executing DDL queries
1964
+ * @description Implements PromiseLike to support both await-based execution and query retrieval
1965
+ *
1966
+ * @example Execute when awaited:
1967
+ * ```ts
1968
+ * await sql.schema().createTable("users", (table) => {
1969
+ * table.addColumn("id", "integer", { primaryKey: true });
1970
+ * });
1971
+ * ```
1972
+ *
1973
+ * @example Get SQL without executing:
1974
+ * ```ts
1975
+ * const sql = sql.schema().createTable("users", (table) => {
1976
+ * table.addColumn("id", "integer", { primaryKey: true });
1977
+ * }).toQuery();
1978
+ * ```
1979
+ *
1980
+ * @example Multiple operations:
1981
+ * ```ts
1982
+ * const builder = sql.schema();
1983
+ * builder.createTable("users", (table) => { ... });
1984
+ * builder.createTable("posts", (table) => { ... });
1985
+ * await builder; // Execute all
1986
+ * ```
1987
+ */
1988
+ declare class SchemaBuilder implements PromiseLike<void> {
1989
+ #private;
1990
+ private schema;
1991
+ private dataSource;
1992
+ private executionPromise;
1993
+ private state;
1994
+ private executionError;
1995
+ constructor(dataSource: SqlDataSource, sqlType?: SqlDataSourceType);
1966
1996
  /**
1967
- * @description Adds a raw statement to define a default value as is
1968
- * @example
1969
- * ```ts
1970
- * schema.rawStatement("CURRENT_TIMESTAMP");
1971
- * schema.alterTable("users", (table) => {
1972
- * table.timestamp("created_at").default(this.schema.rawStatement("CURRENT_TIMESTAMP"));
1973
- * });
1974
- * ```
1997
+ * @description PromiseLike.then implementation - called when awaiting the builder
1998
+ * @description Executes all pending SQL queries on first await
1975
1999
  */
1976
- rawStatement(value: string): RawNode;
2000
+ then<TResult1 = void, TResult2 = never>(onfulfilled?: ((value: void) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): PromiseLike<TResult1 | TResult2>;
1977
2001
  /**
1978
- * @description Add raw query to the migration
2002
+ * @description Adds a raw statement to define a default value as is
1979
2003
  */
1980
- rawQuery(query: string): void;
2004
+ rawStatement(value: string): RawNode;
1981
2005
  /**
1982
- * @description Runs the sql in the given file, throws error if file does not exist or is not .sql or .txt
1983
- * @description File is splitted by semicolons and each statement is executed separately and in order
2006
+ * @description Add raw query to the schema
1984
2007
  */
1985
- runFile(filePath: string): void;
2008
+ rawQuery(query: string): this;
1986
2009
  /**
1987
2010
  * @description Create table constructor
1988
- * @mssql Does not support ifNotExists option
1989
2011
  */
1990
2012
  createTable(table: string, cb: (table: CreateTableBuilder) => void, options?: {
1991
2013
  ifNotExists?: boolean;
1992
- }): void;
2014
+ }): this;
1993
2015
  /**
1994
2016
  * @description Alter table constructor
1995
- * @mssql Limited support - cannot modify columns with constraints; see AlterTableBuilder methods for details
1996
2017
  */
1997
- alterTable(table: string, cb: (t: AlterTableBuilder) => void): void;
2018
+ alterTable(table: string, cb: (t: AlterTableBuilder) => void): this;
1998
2019
  /**
1999
2020
  * @description Drop table in the database
2000
2021
  */
2001
- dropTable(table: string, ifExists?: boolean): void;
2022
+ dropTable(table: string, ifExists?: boolean): this;
2002
2023
  /**
2003
2024
  * @description Rename table in the database
2004
- * @mssql Uses sp_rename procedure; does not update references in views/procedures/triggers
2005
2025
  */
2006
- renameTable(oldTable: string, newTable: string): void;
2026
+ renameTable(oldTable: string, newTable: string): this;
2007
2027
  /**
2008
2028
  * @description Truncate table
2009
2029
  */
2010
- truncateTable(table: string): void;
2030
+ truncateTable(table: string): this;
2011
2031
  /**
2012
2032
  * @description Create index on table
2013
2033
  */
2014
- createIndex(table: string, columns: string[] | string, options: CommonConstraintOptions): void;
2034
+ createIndex(table: string, columns: string[] | string, options?: CommonConstraintOptions): this;
2015
2035
  /**
2016
2036
  * @description Drop index on table
2017
- * @mysql requires table name for index drop
2018
2037
  */
2019
- dropIndex(indexName: string, table?: string): void;
2038
+ dropIndex(indexName: string, table?: string): this;
2020
2039
  /**
2021
2040
  * @description Adds a primary key to a table
2022
2041
  */
2023
- addPrimaryKey(table: string, columns: string[]): void;
2042
+ addPrimaryKey(table: string, columns: string[]): this;
2024
2043
  /**
2025
2044
  * @description Adds a UNIQUE constraint to a table
2026
2045
  */
2027
- addUnique(table: string, columns: string[] | string, options?: CommonConstraintOptions): void;
2046
+ addUnique(table: string, columns: string[] | string, options?: CommonConstraintOptions): this;
2028
2047
  /**
2029
- * @description Drops a foreign key from a table, uses a standard constraint name pattern: fk_${table}_${leftColumn}_${rightColumn}
2030
- * @description If a custom constraint name was used to generate the foreign key, use `dropConstraint` instead
2048
+ * @description Adds a constraint to a table
2031
2049
  */
2032
- dropForeignKey(table: string, leftColumn: string, rightColumn: string): void;
2050
+ addConstraint(table: string, type: string, ...rest: any[]): this;
2033
2051
  /**
2034
- * @description Drops a UNIQUE constraint from a table
2035
- * @description If no constraintName is provided, it computes the default name using columns
2052
+ * @description Drops a primary key from a table
2036
2053
  */
2037
- dropUnique(table: string, columnsOrConstraintName: string | string[], options?: CommonConstraintOptions): void;
2054
+ dropPrimaryKey(table: string): this;
2038
2055
  /**
2039
- * @description Drops a primary key from a table
2056
+ * @description Drops a foreign key from a table
2040
2057
  */
2041
- dropPrimaryKey(table: string): void;
2058
+ dropForeignKey(table: string, leftColumn: string, rightColumn: string): this;
2042
2059
  /**
2043
- * @description Adds a foreign key to a table
2060
+ * @description Drops a UNIQUE constraint from a table
2044
2061
  */
2045
- addConstraint(table: string, ...options: ConstructorParameters<typeof ConstraintNode>): void;
2062
+ dropUnique(table: string, columnsOrConstraintName: string | string[], options?: CommonConstraintOptions): this;
2046
2063
  /**
2047
2064
  * @description Drops a constraint from a table
2048
2065
  */
2049
- dropConstraint(table: string, constraintName: string): void;
2066
+ dropConstraint(table: string, constraintName: string): this;
2050
2067
  /**
2051
2068
  * @description Create database extension, only supported for postgres
2052
- * @postgres Supports extensions like PostGIS, uuid-ossp, hstore, etc.
2053
- * @mysql Extensions are not supported - outputs a comment
2054
- * @sqlite Extensions are loaded dynamically - outputs a comment
2055
- * @mssql Extensions are not supported - outputs a comment
2056
- * @oracledb Extensions are not supported - outputs a comment
2057
2069
  */
2058
- createExtension(extensionName: CommonPostgresExtensions, ifNotExists?: boolean): void;
2059
- createExtension(extensionName: string, ifNotExists?: boolean): void;
2060
- private generateAstInstance;
2070
+ createExtension(extensionName: CommonPostgresExtensions, ifNotExists?: boolean): this;
2071
+ createExtension(extensionName: string, ifNotExists?: boolean): this;
2072
+ /**
2073
+ * @description Returns the SQL statement(s)
2074
+ * @returns Single string if one statement, array if multiple
2075
+ */
2076
+ toQuery(): string | string[];
2077
+ /**
2078
+ * @description Returns all statements as an array
2079
+ */
2080
+ toQueries(): string[];
2081
+ /**
2082
+ * @description Returns the SQL statement(s) as a formatted string
2083
+ */
2084
+ toString(): string;
2085
+ /**
2086
+ * @description Executes all pending SQL queries
2087
+ * @description Can be called explicitly or via await (PromiseLike)
2088
+ */
2089
+ execute(): Promise<void>;
2090
+ /**
2091
+ * @description Returns true if the builder has been executed
2092
+ */
2093
+ isExecuted(): boolean;
2094
+ /**
2095
+ * @description Returns true if the builder is pending execution
2096
+ */
2097
+ isPending(): boolean;
2098
+ /**
2099
+ * @description Returns true if the builder execution failed
2100
+ */
2101
+ hasFailed(): boolean;
2061
2102
  }
2062
2103
 
2063
2104
  type AstParserType = {
@@ -2120,6 +2161,8 @@ type SoftDeleteOptions<T> = {
2120
2161
  ignoreBeforeUpdateHook?: boolean;
2121
2162
  };
2122
2163
 
2164
+ type JsonPathInput = string | (string | number)[];
2165
+
2123
2166
  declare class DeleteNode extends QueryNode {
2124
2167
  fromNode: FromNode;
2125
2168
  chainsWith: string;
@@ -2176,31 +2219,6 @@ declare class UpdateNode extends QueryNode {
2176
2219
  constructor(fromNode: FromNode, columns?: string[], values?: (any | RawNode)[], isRawValue?: boolean);
2177
2220
  }
2178
2221
 
2179
- type PaginationMetadata = {
2180
- perPage: number;
2181
- currentPage: number;
2182
- firstPage: number;
2183
- isEmpty: boolean;
2184
- total: number;
2185
- lastPage: number;
2186
- hasMorePages: boolean;
2187
- hasPages: boolean;
2188
- };
2189
- type CursorPaginationMetadata = {
2190
- perPage: number;
2191
- firstPage: number;
2192
- isEmpty: boolean;
2193
- total: number;
2194
- };
2195
- type PaginatedData<T extends Model, S extends Record<string, any> = {}, R extends Record<string, any> = {}> = {
2196
- paginationMetadata: PaginationMetadata;
2197
- data: ([keyof S] extends [never] ? T & R : SelectedModel<S, R>)[];
2198
- };
2199
- type CursorPaginatedData<T extends Model, S extends Record<string, any> = {}, R extends Record<string, any> = {}> = {
2200
- paginationMetadata: CursorPaginationMetadata;
2201
- data: ([keyof S] extends [never] ? T & R : SelectedModel<S, R>)[];
2202
- };
2203
-
2204
2222
  type BaseValues$1 = string | number | boolean | null;
2205
2223
  type BinaryOperatorType$1 = "=" | "!=" | "<>" | ">" | "<" | ">=" | "<=" | "like" | "ilike" | "in";
2206
2224
  declare class HavingNode extends QueryNode {
@@ -2250,8 +2268,6 @@ declare class WhereGroupNode extends QueryNode {
2250
2268
  constructor(nodes: (WhereNode | WhereGroupNode | WhereSubqueryNode)[], chainsWith?: "and" | "or");
2251
2269
  }
2252
2270
 
2253
- type JsonPathInput = string | (string | number)[];
2254
-
2255
2271
  declare class DistinctNode extends QueryNode {
2256
2272
  chainsWith: string;
2257
2273
  canKeywordBeSeenMultipleTimes: boolean;
@@ -2568,7 +2584,7 @@ type UniqueType = {
2568
2584
  name: string;
2569
2585
  };
2570
2586
 
2571
- declare abstract class FooterQueryBuilder<T extends Model> {
2587
+ declare abstract class FooterQueryBuilder<T extends Model, S extends Record<string, any> = Record<string, any>> {
2572
2588
  protected sqlDataSource: SqlDataSource;
2573
2589
  protected model: typeof Model;
2574
2590
  protected groupByNodes: GroupByNode[];
@@ -2839,7 +2855,7 @@ declare class JoinOnQueryBuilder {
2839
2855
  * @description Callback type for join conditions
2840
2856
  */
2841
2857
  type JoinOnCallback = (query: JoinOnQueryBuilder) => void;
2842
- declare abstract class JoinQueryBuilder<T extends Model> extends FooterQueryBuilder<T> {
2858
+ declare abstract class JoinQueryBuilder<T extends Model, S extends Record<string, any> = Record<string, any>> extends FooterQueryBuilder<T, S> {
2843
2859
  protected joinNodes: JoinNode[];
2844
2860
  protected constructor(model: typeof Model, sqlDataSource: SqlDataSource);
2845
2861
  /**
@@ -2941,7 +2957,7 @@ declare abstract class JoinQueryBuilder<T extends Model> extends FooterQueryBuil
2941
2957
  fullJoin(relationTable: string, referencingColumnOrPrimaryColumn: JoinableColumn, primaryColumn: JoinableColumn, callback: JoinOnCallback): this;
2942
2958
  }
2943
2959
 
2944
- declare class SelectQueryBuilder<T extends Model> extends JoinQueryBuilder<T> {
2960
+ declare class SelectQueryBuilder<T extends Model, S extends Record<string, any> = Record<string, any>> extends JoinQueryBuilder<T, S> {
2945
2961
  protected dbType: SqlDataSourceType;
2946
2962
  protected modelSelectedColumns: string[];
2947
2963
  protected withQuery?: string;
@@ -2953,31 +2969,30 @@ declare class SelectQueryBuilder<T extends Model> extends JoinQueryBuilder<T> {
2953
2969
  /**
2954
2970
  * @description Adds a SELECT condition to the query.
2955
2971
  * @description Can be stacked multiple times
2956
- * @description Supports: "column", "table.column", "column as alias", "*", "table.*"
2972
+ * @description Supports: "column", "table.column", "*", "table.*", or [column, alias] tuples
2957
2973
  * @example
2958
- * ```ts
2959
- * const user = await User.query().select("name", "age").one(); // SELECT name, age FROM users
2960
- * const user = await User.query().select("name", "users.age").one(); // SELECT name, users.age FROM users
2961
- * const user = await User.query().select("name as userName").one(); // SELECT name as userName FROM users
2962
- * ```
2974
+ * .select("id", "name") // Simple columns
2975
+ * .select(["id", "userId"], ["name", "userName"]) // Columns with aliases
2976
+ * .select("id", ["name", "userName"]) // Mixed
2963
2977
  */
2964
- select<S extends string>(...columns: SelectableColumn$1<S>[]): this;
2965
- select(...columns: (ModelKey<T> | "*")[]): this;
2978
+ select<C extends string>(...columns: (SelectableColumn$1<C> | Selectable)[]): this;
2979
+ select(...columns: (ModelKey<T> | "*" | Selectable)[]): this;
2966
2980
  /**
2967
- * @description Parses a column string that may contain an alias (e.g., "column as alias")
2968
- * @returns The column part and optional alias part
2981
+ * @description Adds a raw SELECT statement to the query
2969
2982
  */
2970
- private parseColumnAlias;
2983
+ selectRaw(statement: string): this;
2971
2984
  /**
2972
- * @description Adds a raw SELECT statement to the query
2973
- * @description Useful for SQL functions, expressions, or complex selections
2985
+ * @description Selects a SQL function applied to a column with a typed alias.
2986
+ * @description Provides intellisense for common SQL functions while accepting any custom function.
2987
+ * @param func The SQL function name (count, sum, avg, min, max, upper, lower, etc.)
2988
+ * @param column The column to apply the function to (use "*" for count(*))
2989
+ * @param alias The alias for the result
2974
2990
  * @example
2975
- * ```ts
2976
- * const result = await User.query().selectRaw("count(*) as total").one();
2977
- * const result = await User.query().selectRaw("sum(amount) as total_amount").one();
2978
- * ```
2991
+ * .selectFunc("count", "*", "total")
2992
+ * .selectFunc("upper", "name", "upperName")
2993
+ * .selectFunc("custom_fn", "column", "result")
2979
2994
  */
2980
- selectRaw(statement: string): this;
2995
+ selectFunc<A extends string>(sqlFunc: SqlFunction, column: string, alias: A): this;
2981
2996
  /**
2982
2997
  * @description Clears the SELECT clause
2983
2998
  */
@@ -2996,13 +3011,10 @@ declare class SelectQueryBuilder<T extends Model> extends JoinQueryBuilder<T> {
2996
3011
  clearDistinctOn(): this;
2997
3012
  /**
2998
3013
  * @description Sets the table to select from, by default is the table defined in the Model
2999
- * @description Can be used on non select queries too, it will only specify the table name (es. INSERT INTO $table)
3000
- * @param table The table name to query from, must be in valid sql format `table` or `table as alias`
3001
3014
  */
3002
- from<S extends string>(table: TableFormat<S>): this;
3015
+ from<F extends string>(table: TableFormat<F>): this;
3003
3016
  /**
3004
3017
  * @description Sets the table to select from, by default is the table defined in the Model
3005
- * @description Better naming convention for non select queries
3006
3018
  * @alias from
3007
3019
  */
3008
3020
  table(table: string): this;
@@ -3011,159 +3023,38 @@ declare class SelectQueryBuilder<T extends Model> extends JoinQueryBuilder<T> {
3011
3023
  */
3012
3024
  distinct(): this;
3013
3025
  /**
3014
- * @description Adds a DISTINCT ON clause to the query, does not stack, only the last one will be used
3015
- * @warning Cannot use both DISTINCT and DISTINCT ON in the same query, only the DISTINCT ON will be used
3026
+ * @description Adds a DISTINCT ON clause to the query
3016
3027
  * @postgresql Only usable with PostgreSQL
3017
3028
  */
3018
3029
  distinctOn(...columns: ModelKey<T>[]): this;
3019
- distinctOn<S extends string>(...columns: SelectableColumn$1<S>[]): this;
3030
+ distinctOn<C extends string>(...columns: SelectableColumn$1<C>[]): this;
3020
3031
  /**
3021
3032
  * @description Selects a JSON value at the specified path and returns it as JSON
3022
- * @param column The column containing JSON data
3023
- * @param path The JSON path to extract (standardized format: "$.user.name", "user.name", or ["user", "name"])
3024
- * @param alias The alias for the selected value
3025
- * @description Path format is standardized across all databases - ORM converts to DB-specific syntax
3026
- * @example
3027
- * ```ts
3028
- * // All databases accept the same path format:
3029
- * const user = await User.query().selectJson("data", "$.user.name", "userName").one();
3030
- *
3031
- * await User.query().selectJson("data", "user.name", "userName").one(); // $ is optional
3032
- * await User.query().selectJson("data", ["user", "name"], "userName").one();
3033
- *
3034
- * // Array indices:
3035
- * await User.query().selectJson("data", "items.0.name", "firstItemName").one();
3036
- * await User.query().selectJson("data", ["items", 0, "name"], "firstItemName").one();
3037
- * ```
3038
3033
  */
3039
3034
  selectJson<A extends string>(column: ModelKey<T>, path: JsonPathInput, alias: A): this;
3040
3035
  selectJson<A extends string>(column: string, path: JsonPathInput, alias: A): this;
3041
3036
  /**
3042
3037
  * @description Selects a JSON value at the specified path and returns it as text
3043
- * @param column The column containing JSON data
3044
- * @param path The JSON path to extract (standardized format)
3045
- * @param alias The alias for the selected value
3046
- * @description Path format is standardized across all databases - ORM converts to DB-specific syntax
3047
- * @example
3048
- * ```ts
3049
- * // All databases accept the same path format:
3050
- * const user = await User.query().selectJsonText("data", "$.user.name", "userName").one();
3051
- *
3052
- * await User.query().selectJsonText("data", ["user", "name"], "userName").one();
3053
- * ```
3054
3038
  */
3055
3039
  selectJsonText<A extends string>(column: ModelKey<T>, path: JsonPathInput, alias: A): this;
3056
3040
  selectJsonText<A extends string>(column: string, path: JsonPathInput, alias: A): this;
3057
3041
  /**
3058
3042
  * @description Selects the length of a JSON array
3059
- * @param column The column containing JSON array data
3060
- * @param path The JSON path to the array (standardized format, use "$" or "" for root)
3061
- * @param alias The alias for the length value
3062
- * @description Path format is standardized across all databases - ORM converts to DB-specific syntax
3063
- * @example
3064
- * ```ts
3065
- * // All databases accept the same path format:
3066
- * const user = await User.query().selectJsonArrayLength("data", "$.items", "itemCount").one();
3067
- *
3068
- * await User.query().selectJsonArrayLength("data", "items", "itemCount").one();
3069
- * await User.query().selectJsonArrayLength("data", "$", "totalCount").one(); // root array
3070
- * ```
3071
3043
  */
3072
3044
  selectJsonArrayLength<A extends string>(column: ModelKey<T>, path: JsonPathInput, alias: A): this;
3073
3045
  selectJsonArrayLength<A extends string>(column: string, path: JsonPathInput, alias: A): this;
3074
3046
  /**
3075
3047
  * @description Selects the keys of a JSON object
3076
- * @param column The column containing JSON object data
3077
- * @param path The JSON path to the object (standardized format, use "$" or "" for root)
3078
- * @param alias The alias for the keys
3079
- * @description Path format is standardized across all databases - ORM converts to DB-specific syntax
3080
- * @postgres Returns an array of keys
3081
- * @mysql Returns a JSON array of keys
3082
- * @example
3083
- * ```ts
3084
- * // All databases accept the same path format:
3085
- * const user = await User.query().selectJsonKeys("data", "$.user", "userKeys").one();
3086
- *
3087
- * await User.query().selectJsonKeys("data", "user", "userKeys").one();
3088
- * await User.query().selectJsonKeys("data", "$", "rootKeys").one(); // root object
3089
- * ```
3090
3048
  */
3091
3049
  selectJsonKeys<A extends string>(column: ModelKey<T>, path: JsonPathInput, alias: A): this;
3092
3050
  selectJsonKeys<A extends string>(column: string, path: JsonPathInput, alias: A): this;
3093
3051
  /**
3094
3052
  * @description Adds a raw JSON select expression
3095
- * @param raw The raw SQL expression
3096
- * @param alias The alias for the selected value
3097
- * @example
3098
- * ```ts
3099
- * const user = await User.query().selectJsonRaw("data->>'email'", "userEmail").one();
3100
- * ```
3101
3053
  */
3102
3054
  selectJsonRaw<A extends string>(raw: string, alias: A): this;
3103
- /**
3104
- * @description Selects COUNT(column) with an alias
3105
- * @param column The column to count (use "*" for COUNT(*))
3106
- * @param alias The alias for the count result
3107
- * @example
3108
- * ```ts
3109
- * const result = await User.query().selectCount("id", "totalUsers").one();
3110
- *
3111
- * const result = await User.query().selectCount("*", "total").one();
3112
- * ```
3113
- */
3114
- selectCount<A extends string>(column: ModelKey<T> | "*", alias: A): this;
3115
- selectCount<A extends string>(column: string, alias: A): this;
3116
- /**
3117
- * @description Selects SUM(column) with an alias
3118
- * @param column The column to sum
3119
- * @param alias The alias for the sum result
3120
- * @example
3121
- * ```ts
3122
- * const result = await Order.query().selectSum("amount", "totalAmount").one();
3123
- * console.log(result?.totalAmount); // number
3124
- * ```
3125
- */
3126
- selectSum<A extends string>(column: ModelKey<T>, alias: A): this;
3127
- selectSum<A extends string>(column: string, alias: A): this;
3128
- /**
3129
- * @description Selects AVG(column) with an alias
3130
- * @param column The column to average
3131
- * @param alias The alias for the average result
3132
- * @example
3133
- * ```ts
3134
- * const result = await User.query().selectAvg("age", "averageAge").one();
3135
- * console.log(result?.averageAge); // number
3136
- * ```
3137
- */
3138
- selectAvg<A extends string>(column: ModelKey<T>, alias: A): this;
3139
- selectAvg<A extends string>(column: string, alias: A): this;
3140
- /**
3141
- * @description Selects MIN(column) with an alias
3142
- * @param column The column to get minimum value
3143
- * @param alias The alias for the min result
3144
- * @example
3145
- * ```ts
3146
- * const result = await User.query().selectMin("age", "youngestAge").one();
3147
- * console.log(result?.youngestAge); // number
3148
- * ```
3149
- */
3150
- selectMin<A extends string>(column: ModelKey<T>, alias: A): this;
3151
- selectMin<A extends string>(column: string, alias: A): this;
3152
- /**
3153
- * @description Selects MAX(column) with an alias
3154
- * @param column The column to get maximum value
3155
- * @param alias The alias for the max result
3156
- * @example
3157
- * ```ts
3158
- * const result = await User.query().selectMax("age", "oldestAge").one();
3159
- * console.log(result?.oldestAge); // number
3160
- * ```
3161
- */
3162
- selectMax<A extends string>(column: ModelKey<T>, alias: A): this;
3163
- selectMax<A extends string>(column: string, alias: A): this;
3164
3055
  }
3165
3056
 
3166
- declare abstract class WhereQueryBuilder<T extends Model> extends SelectQueryBuilder<T> {
3057
+ declare abstract class WhereQueryBuilder<T extends Model, S extends Record<string, any> = Record<string, any>> extends SelectQueryBuilder<T, S> {
3167
3058
  protected whereNodes: (WhereNode | WhereGroupNode | WhereSubqueryNode)[];
3168
3059
  protected havingNodes: HavingNode[];
3169
3060
  protected isNestedCondition: boolean;
@@ -3500,7 +3391,7 @@ declare abstract class WhereQueryBuilder<T extends Model> extends SelectQueryBui
3500
3391
  }
3501
3392
 
3502
3393
  type JsonParam = Record<string, unknown> | any[];
3503
- declare class JsonQueryBuilder<T extends Model> extends WhereQueryBuilder<T> {
3394
+ declare class JsonQueryBuilder<T extends Model, S extends Record<string, any> = Record<string, any>> extends WhereQueryBuilder<T, S> {
3504
3395
  /**
3505
3396
  * @description Filters records matching exact JSON value.
3506
3397
  */
@@ -3589,7 +3480,7 @@ declare class JsonQueryBuilder<T extends Model> extends WhereQueryBuilder<T> {
3589
3480
  orWhereJsonRaw(raw: string, params?: any[]): this;
3590
3481
  }
3591
3482
 
3592
- declare class QueryBuilder<T extends Model = any> extends JsonQueryBuilder<T> {
3483
+ declare class QueryBuilder<T extends Model = any, S extends Record<string, any> = Record<string, any>> extends JsonQueryBuilder<T, S> {
3593
3484
  model: typeof Model;
3594
3485
  protected astParser: AstParser;
3595
3486
  protected unionNodes: UnionNode[];
@@ -3608,23 +3499,23 @@ declare class QueryBuilder<T extends Model = any> extends JsonQueryBuilder<T> {
3608
3499
  */
3609
3500
  performance: {
3610
3501
  many: (returnType?: "millis" | "seconds") => Promise<{
3611
- data: T[];
3502
+ data: S[];
3612
3503
  time: number;
3613
3504
  }>;
3614
3505
  one: (returnType?: "millis" | "seconds") => Promise<{
3615
- data: T | null;
3506
+ data: S | null;
3616
3507
  time: number;
3617
3508
  }>;
3618
3509
  oneOrFail: (returnType?: "millis" | "seconds") => Promise<{
3619
- data: T;
3510
+ data: S;
3620
3511
  time: number;
3621
3512
  }>;
3622
3513
  paginate: (page: number, perPage: number, returnType?: "millis" | "seconds") => Promise<{
3623
- data: PaginatedData<T>;
3514
+ data: RawPaginatedData<S>;
3624
3515
  time: number;
3625
3516
  }>;
3626
3517
  paginateWithCursor: (page: number, options: PaginateWithCursorOptions<T, ModelKey<T>>, cursor?: Cursor<T, ModelKey<T>>, returnType?: "millis" | "seconds") => Promise<{
3627
- data: [CursorPaginatedData<T>, Cursor<T, ModelKey<T>>];
3518
+ data: [RawCursorPaginatedData<S>, Cursor<T, ModelKey<T>>];
3628
3519
  time: number;
3629
3520
  }>;
3630
3521
  exists: (returnType?: "millis" | "seconds") => Promise<{
@@ -3669,6 +3560,75 @@ declare class QueryBuilder<T extends Model = any> extends JsonQueryBuilder<T> {
3669
3560
  * @description If set to "slave", read operations will use slave and write operations will use master
3670
3561
  */
3671
3562
  setReplicationMode(replicationMode: ReplicationType): this;
3563
+ /**
3564
+ * @description Adds a SELECT condition to the query with type safety.
3565
+ * @description Can be stacked multiple times
3566
+ * @description Supports: "column", "table.column", "*", "table.*", or [column, alias] tuples
3567
+ * @example
3568
+ * ```ts
3569
+ * const user = await sql.query("users").select("name", "age").one();
3570
+ * // user type: { name: any, age: any } | null
3571
+ *
3572
+ * const user = await sql.query("users").select(["name", "userName"]).one();
3573
+ * // user type: { userName: any } | null
3574
+ * ```
3575
+ */
3576
+ select<const Columns extends readonly Selectable[]>(...columns: Columns): QueryBuilder<T, ComposeBuildRawSelect<S, Columns>>;
3577
+ /**
3578
+ * @description Adds a raw SELECT statement to the query with type safety.
3579
+ * @description Use the generic parameter to specify the type of the selected columns.
3580
+ * @example
3581
+ * ```ts
3582
+ * const result = await sql.query("users")
3583
+ * .selectRaw<{ total: number }>("count(*) as total")
3584
+ * .one();
3585
+ * // result type: { total: number } | null
3586
+ * ```
3587
+ */
3588
+ selectRaw<Added extends Record<string, any> = Record<string, any>>(statement: string): QueryBuilder<T, ComposeRawSelect<S, Added>>;
3589
+ /**
3590
+ * @description Clears the SELECT clause and resets type to default
3591
+ */
3592
+ clearSelect(): QueryBuilder<T, Record<string, any>>;
3593
+ /**
3594
+ * @description Selects a SQL function applied to a column with a typed alias.
3595
+ * @description Provides intellisense for common SQL functions while accepting any custom function.
3596
+ * @description Return type is auto-inferred based on function name (number for count/sum/avg, string for upper/lower/trim, etc.)
3597
+ * @param sqlFunc The SQL function name (count, sum, avg, min, max, upper, lower, etc.)
3598
+ * @param column The column to apply the function to (use "*" for count(*))
3599
+ * @param alias The alias for the result
3600
+ * @example
3601
+ * ```ts
3602
+ * const result = await sql.query("users")
3603
+ * .selectFunc("count", "*", "total")
3604
+ * .one();
3605
+ * // result type: { total: number } | null - auto-inferred!
3606
+ * ```
3607
+ */
3608
+ selectFunc<F extends SqlFunction, Alias extends string>(sqlFunc: F, column: string, alias: Alias): QueryBuilder<T, ComposeRawSelect<S, {
3609
+ [K in Alias]: SqlFunctionReturnType<F>;
3610
+ }>>;
3611
+ /**
3612
+ * @description Selects a subquery, subquery must return a single column
3613
+ */
3614
+ selectSubQuery<ValueType = any, Alias extends string = string>(cbOrQueryBuilder: ((subQuery: QueryBuilder<T>) => void) | QueryBuilder<any>, alias: Alias): QueryBuilder<T, ComposeRawSelect<S, {
3615
+ [K in Alias]: ValueType;
3616
+ }>>;
3617
+ selectJson<ValueType = any, Alias extends string = string>(column: ModelKey<T> | string, path: JsonPathInput, alias: Alias): QueryBuilder<T, ComposeRawSelect<S, {
3618
+ [K in Alias]: ValueType;
3619
+ }>>;
3620
+ selectJsonText<ValueType = string, Alias extends string = string>(column: ModelKey<T> | string, path: JsonPathInput, alias: Alias): QueryBuilder<T, ComposeRawSelect<S, {
3621
+ [K in Alias]: ValueType;
3622
+ }>>;
3623
+ selectJsonArrayLength<Alias extends string = string>(column: ModelKey<T> | string, path: JsonPathInput, alias: Alias): QueryBuilder<T, ComposeRawSelect<S, {
3624
+ [K in Alias]: number;
3625
+ }>>;
3626
+ selectJsonKeys<Alias extends string = string>(column: ModelKey<T> | string, path: JsonPathInput, alias: Alias): QueryBuilder<T, ComposeRawSelect<S, {
3627
+ [K in Alias]: string[];
3628
+ }>>;
3629
+ selectJsonRaw<ValueType = any, Alias extends string = string>(raw: string, alias: Alias): QueryBuilder<T, ComposeRawSelect<S, {
3630
+ [K in Alias]: ValueType;
3631
+ }>>;
3672
3632
  /**
3673
3633
  * @description Executes the query and returns true if the query returns at least one result, false otherwise.
3674
3634
  */
@@ -3676,7 +3636,7 @@ declare class QueryBuilder<T extends Model = any> extends JsonQueryBuilder<T> {
3676
3636
  /**
3677
3637
  * @description Executes the query and retrieves multiple results.
3678
3638
  */
3679
- many(): Promise<T[]>;
3639
+ many(): Promise<S[]>;
3680
3640
  /**
3681
3641
  * @description Executes the query and retrieves a single column from the results.
3682
3642
  * @param key - The column to retrieve from the results, must be a Model Column
@@ -3685,18 +3645,18 @@ declare class QueryBuilder<T extends Model = any> extends JsonQueryBuilder<T> {
3685
3645
  /**
3686
3646
  * @description Executes the query and retrieves a single result.
3687
3647
  */
3688
- one(): Promise<T | null>;
3648
+ one(): Promise<S | null>;
3689
3649
  /**
3690
3650
  * @description Executes the query and retrieves the first result. Fail if no result is found.
3691
3651
  */
3692
- oneOrFail(): Promise<T>;
3652
+ oneOrFail(): Promise<S>;
3693
3653
  /**
3694
3654
  * @description Executes the query and returns a node readable stream.
3695
3655
  * @description If used by a model query builder, it will serialize the models and apply the hooks and relations.
3696
3656
  * @postgres needs the pg-query-stream package in order to work
3697
3657
  * @throws If using postgres and the `pg-query-stream` package is not installed
3698
3658
  */
3699
- stream<M extends Model = T>(options?: StreamOptions): Promise<PassThrough & AsyncGenerator<M>>;
3659
+ stream<M = S>(options?: StreamOptions): Promise<PassThrough & AsyncGenerator<M>>;
3700
3660
  /**
3701
3661
  * @description Chunks the query into smaller queries, it returns a generator of the chunks
3702
3662
  * @description It will continue to yield chunks until the query returns no results
@@ -3726,7 +3686,7 @@ declare class QueryBuilder<T extends Model = any> extends JsonQueryBuilder<T> {
3726
3686
  *
3727
3687
  * console.log(chunks);
3728
3688
  */
3729
- chunk(chunkSize: number): AsyncGenerator<T[], void, unknown>;
3689
+ chunk(chunkSize: number): AsyncGenerator<S[], void, unknown>;
3730
3690
  /**
3731
3691
  * @description Executes the query and retrieves multiple paginated results.
3732
3692
  * @description Overrides the limit and offset clauses in order to paginate the results.
@@ -3740,11 +3700,7 @@ declare class QueryBuilder<T extends Model = any> extends JsonQueryBuilder<T> {
3740
3700
  * @warning If no order by clause is present in the query, the query will add an order by clause to the query `orderBy(discriminator, "asc")`
3741
3701
  * @returns the pagination metadata and the cursor for the next page
3742
3702
  */
3743
- paginateWithCursor<K extends ModelKey<T>>(limit: number, options: PaginateWithCursorOptions<T, K>, cursor?: Cursor<T, K>): Promise<[CursorPaginatedData<T>, Cursor<T, K>]>;
3744
- /**
3745
- * @description Selects a subquery, subquery must return a single column
3746
- */
3747
- selectSubQuery(cbOrQueryBuilder: ((subQuery: QueryBuilder<T>) => void) | QueryBuilder<any>, alias: string): this;
3703
+ paginateWithCursor<K extends ModelKey<T>>(limit: number, options: PaginateWithCursorOptions<T, K>, cursor?: Cursor<T, K>): Promise<[RawCursorPaginatedData<S>, Cursor<T, K>]>;
3748
3704
  /**
3749
3705
  * @description Locks the table for update
3750
3706
  * @param skipLocked - If true, the query will skip locked rows
@@ -3814,7 +3770,7 @@ declare class QueryBuilder<T extends Model = any> extends JsonQueryBuilder<T> {
3814
3770
  * @description Executes the query and retrieves multiple paginated results.
3815
3771
  * @description Overrides the limit and offset clauses in order to paginate the results.
3816
3772
  */
3817
- paginate(page: number, perPage: number): Promise<PaginatedData<T>>;
3773
+ paginate(page: number, perPage: number): Promise<RawPaginatedData<S>>;
3818
3774
  /**
3819
3775
  * @description Overrides the from clause in the query.
3820
3776
  */
@@ -3901,11 +3857,11 @@ declare class QueryBuilder<T extends Model = any> extends JsonQueryBuilder<T> {
3901
3857
  /**
3902
3858
  * @description Returns a deep clone of the query builder instance.
3903
3859
  */
3904
- clone(): this;
3860
+ clone(): QueryBuilder<T, S>;
3905
3861
  /**
3906
3862
  * @description Gives a fresh instance of the query builder
3907
3863
  */
3908
- clear(): QueryBuilder<any>;
3864
+ clear(): QueryBuilder<T, Record<string, any>>;
3909
3865
  /**
3910
3866
  * @description Removes the lock query
3911
3867
  */
@@ -3972,7 +3928,7 @@ declare class QueryBuilder<T extends Model = any> extends JsonQueryBuilder<T> {
3972
3928
  /**
3973
3929
  * Allows to get queries without executing them
3974
3930
  */
3975
- declare class DryQueryBuilder extends QueryBuilder {
3931
+ declare class DryQueryBuilder<T extends Model = any, S extends Record<string, any> = Record<string, any>> extends QueryBuilder<T, S> {
3976
3932
  constructor(model: typeof Model, sqlDataSource: SqlDataSource);
3977
3933
  many(): this;
3978
3934
  /**
@@ -4026,9 +3982,160 @@ declare class DryQueryBuilder extends QueryBuilder {
4026
3982
  }
4027
3983
 
4028
3984
  type PluckReturnType<T extends Model, K extends ModelKey<T>> = T[K] extends infer U ? U[] : never;
3985
+ /**
3986
+ * Common SQL functions with intellisense support.
3987
+ * Provides autocomplete for standard SQL aggregate and scalar functions,
3988
+ * while still allowing any custom function name via string fallback.
3989
+ *
3990
+ * @example
3991
+ * selectFunc("count", "*", "total") // Intellisense suggests "count"
3992
+ * selectFunc("custom_fn", "col", "res") // Custom functions still work
3993
+ */
3994
+ type SqlFunction = "count" | "sum" | "avg" | "min" | "max" | "upper" | "lower" | "length" | "trim" | "abs" | "round" | "coalesce" | "ceil" | "floor" | "sqrt" | (string & {});
3995
+ /**
3996
+ * Maps SQL function names to their return types.
3997
+ * Used by selectFunc to auto-infer the result type.
3998
+ *
3999
+ * - Numeric functions (count, sum, avg, etc.) → number
4000
+ * - String functions (upper, lower, trim) → string
4001
+ * - Unknown functions → any
4002
+ */
4003
+ type SqlFunctionReturnType<F extends string> = F extends "count" | "sum" | "avg" | "min" | "max" | "length" | "abs" | "round" | "ceil" | "floor" | "sqrt" ? number : F extends "upper" | "lower" | "trim" ? string : any;
4004
+ /**
4005
+ * A tuple type for selecting a column with an alias.
4006
+ * @example ["id", "userId"] selects "id" column as "userId"
4007
+ */
4008
+ type SelectTuple<C extends string = string, A extends string = string> = readonly [column: C, alias: A];
4009
+ /**
4010
+ * Input type for select() method in raw query builder.
4011
+ * Accepts either a column string or a [column, alias] tuple.
4012
+ *
4013
+ * @example
4014
+ * .select("id", "name") // Simple columns
4015
+ * .select(["id", "userId"], ["name", "n"]) // Columns with aliases
4016
+ * .select("id", ["name", "userName"]) // Mixed
4017
+ */
4018
+ type Selectable = string | SelectTuple;
4019
+ /**
4020
+ * Unique symbol used internally to mark that a raw select() has been called.
4021
+ */
4022
+ declare const RAW_SELECT_BRAND: unique symbol;
4023
+ /**
4024
+ * Marker type to indicate that a raw select() has been called.
4025
+ * @internal
4026
+ */
4027
+ type RawSelectBrand = {
4028
+ [RAW_SELECT_BRAND]?: never;
4029
+ };
4030
+ /**
4031
+ * Utility type to convert a union to an intersection.
4032
+ * @internal
4033
+ */
4034
+ type UnionToIntersection$1<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
4035
+ /**
4036
+ * Extracts the final property name from a column selection for raw queries.
4037
+ * Supports both string columns and [column, alias] tuples.
4038
+ *
4039
+ * | Input | Output |
4040
+ * |------------------------------|---------------|
4041
+ * | `"name"` | `"name"` |
4042
+ * | `"users.name"` | `"name"` |
4043
+ * | `["name", "userName"]` | `"userName"` |
4044
+ * | `["users.id", "id"]` | `"id"` |
4045
+ * | `"*"` | `never` |
4046
+ * | `"users.*"` | `never` |
4047
+ */
4048
+ type ExtractRawColumnName<S> = S extends readonly [
4049
+ string,
4050
+ infer Alias extends string
4051
+ ] ? Alias : S extends string ? S extends "*" ? never : S extends `${string}.*` ? never : S extends `${string}.${infer Column}` ? Column extends "*" ? never : Column : S : never;
4052
+ /**
4053
+ * Builds the type for a single selected column in a raw query.
4054
+ * All column types are `any` since we don't have model type information.
4055
+ * Supports both string columns and [column, alias] tuples.
4056
+ *
4057
+ * | Selection | Result Type |
4058
+ * |------------------------|---------------------------------------|
4059
+ * | `"*"` | `Record<string, any>` |
4060
+ * | `"table.*"` | `Record<string, any>` |
4061
+ * | `"column"` | `{ column: any }` |
4062
+ * | `["col", "alias"]` | `{ alias: any }` |
4063
+ *
4064
+ * @internal
4065
+ */
4066
+ type BuildRawSingleSelectType<S> = S extends readonly [
4067
+ string,
4068
+ infer Alias extends string
4069
+ ] ? {
4070
+ [K in Alias]: any;
4071
+ } : S extends string ? S extends "*" ? Record<string, any> : S extends `${string}.*` ? Record<string, any> : ExtractRawColumnName<S> extends never ? {} : {
4072
+ [K in ExtractRawColumnName<S> & string]: any;
4073
+ } : {};
4074
+ /**
4075
+ * Checks if a column selection includes wildcards or is empty.
4076
+ * @internal
4077
+ */
4078
+ type HasRawStarOrEmpty<Columns extends readonly Selectable[]> = Columns["length"] extends 0 ? true : "*" extends Columns[number] ? true : false;
4079
+ /**
4080
+ * Builds the combined TypeScript type for multiple selected columns in a raw query.
4081
+ * Supports both string columns and [column, alias] tuples.
4082
+ *
4083
+ * ## Rules
4084
+ *
4085
+ * 1. **Empty selection or `*`**: Returns `Record<string, any>`
4086
+ * 2. **Specific columns**: Returns intersection of all selected column types (all `any`)
4087
+ * 3. **With `table.*`**: Adds `Record<string, any>` to allow unknown properties
4088
+ *
4089
+ * @example
4090
+ * // .select("name", ["age", "userAge"])
4091
+ * BuildRawSelectType<["name", ["age", "userAge"]]>
4092
+ * // Result: { name: any; userAge: any } & RawSelectBrand
4093
+ *
4094
+ * @example
4095
+ * // .select("*")
4096
+ * BuildRawSelectType<["*"]>
4097
+ * // Result: Record<string, any>
4098
+ */
4099
+ type BuildRawSelectType<Columns extends readonly Selectable[]> = HasRawStarOrEmpty<Columns> extends true ? Record<string, any> : UnionToIntersection$1<{
4100
+ [K in keyof Columns]: BuildRawSingleSelectType<Columns[K]>;
4101
+ }[number]> extends infer Result ? Result extends Record<string, any> ? keyof Result extends never ? Record<string, any> : Result & RawSelectBrand : Record<string, any> : Record<string, any>;
4102
+ /**
4103
+ * Composes a new selection with the existing selection state for raw queries.
4104
+ *
4105
+ * - If S is the default Record<string, any> (no previous select), returns just the new selection
4106
+ * - If S already has RawSelectBrand (from a previous select), composes with new selection
4107
+ *
4108
+ * @typeParam S - Current selection state
4109
+ * @typeParam Added - New fields being added by the select
4110
+ *
4111
+ * @example
4112
+ * // First selectRaw - creates new selection
4113
+ * ComposeRawSelect<Record<string, any>, { count: number }>
4114
+ * // Result: RawSelectBrand & { count: number }
4115
+ *
4116
+ * @example
4117
+ * // Chained selectRaw - composes with previous
4118
+ * ComposeRawSelect<{ count: number } & RawSelectBrand, { userName: string }>
4119
+ * // Result: { count: number } & RawSelectBrand & { userName: string }
4120
+ */
4121
+ type ComposeRawSelect<S extends Record<string, any>, Added extends Record<string, any>> = (typeof RAW_SELECT_BRAND extends keyof S ? S : RawSelectBrand) & Added;
4122
+ /**
4123
+ * Composes a BuildRawSelectType result with the existing selection state.
4124
+ *
4125
+ * Similar to ComposeRawSelect but designed for use with BuildRawSelectType.
4126
+ *
4127
+ * @typeParam S - Current selection state
4128
+ * @typeParam Columns - The columns being selected
4129
+ */
4130
+ type ComposeBuildRawSelect<S extends Record<string, any>, Columns extends readonly Selectable[]> = (typeof RAW_SELECT_BRAND extends keyof S ? S : {}) & BuildRawSelectType<Columns>;
4029
4131
  type WhereOnlyQueryBuilder<T extends Model> = Pick<WhereQueryBuilder<T>, "where" | "andWhere" | "orWhere" | "whereNot" | "andWhereNot" | "orWhereNot" | "whereIn" | "andWhereIn" | "orWhereIn" | "whereNotIn" | "andWhereNotIn" | "orWhereNotIn" | "whereBetween" | "andWhereBetween" | "orWhereBetween" | "whereNotBetween" | "andWhereNotBetween" | "orWhereNotBetween" | "whereNull" | "andWhereNull" | "orWhereNull" | "whereNotNull" | "andWhereNotNull" | "orWhereNotNull" | "whereLike" | "andWhereLike" | "orWhereLike" | "whereILike" | "andWhereILike" | "orWhereILike" | "whereNotLike" | "andWhereNotLike" | "orWhereNotLike" | "whereNotILike" | "andWhereNotILike" | "orWhereNotILike" | "whereRegexp" | "andWhereRegexp" | "orWhereRegexp" | "whereNotRegexp" | "andWhereNotRegexp" | "orWhereNotRegexp" | "whereRaw" | "andWhereRaw" | "orWhereRaw" | "whereExists" | "orWhereExists" | "andWhereExists"> & Pick<JsonQueryBuilder<T>, "whereJson" | "andWhereJson" | "orWhereJson" | "whereJsonContains" | "andWhereJsonContains" | "orWhereJsonContains" | "whereJsonNotContains" | "andWhereJsonNotContains" | "orWhereJsonNotContains" | "whereJsonNotContains" | "andWhereJsonNotContains" | "orWhereJsonNotContains" | "whereJsonRaw" | "andWhereJsonRaw" | "orWhereJsonRaw" | "whereJsonNotContains" | "andWhereJsonNotContains" | "orWhereJsonNotContains">;
4030
4132
  type RelationRetrieveMethod<P extends any> = P extends any[] ? "many" : "one";
4031
- type SelectableColumn$1<T extends string = string> = T extends `${infer Table}.${infer Column}.${string}` ? never : T extends `${string}(${string})` ? T : T extends `${string} as ${string}` ? T : T extends `${string} ${string}` ? never : T extends `.${string}` | `${string}.` ? never : T extends `${string}-${string}` ? never : T extends `${string}.${string}` ? T : T;
4133
+ /**
4134
+ * Validates a column string for raw query builder select().
4135
+ * Use [column, alias] tuple format for aliases instead of "column as alias".
4136
+ * Use selectFunction() for SQL functions instead of embedding them in select().
4137
+ */
4138
+ type SelectableColumn$1<T extends string = string> = T extends `${string}.${string}.${string}` ? never : T extends `${string} ${string}` ? never : T extends `.${string}` | `${string}.` ? never : T extends `${string}-${string}` ? never : T extends `${string}.${string}` ? T : T;
4032
4139
  /**
4033
4140
  * @description A column that can be used in a join statement e.g. `users.id`
4034
4141
  */
@@ -4061,9 +4168,37 @@ type UpsertOptionsRawBuilder = {
4061
4168
  updateOnConflict?: boolean;
4062
4169
  returning?: string[];
4063
4170
  };
4064
- type DryQueryBuilderWithoutReadOperations = Omit<DryQueryBuilder, "many" | "one" | "oneOrFail" | "first" | "firstOrFail" | "paginate" | "paginateWithCursor" | "exists" | "pluck" | "increment" | "decrement" | "getSum" | "getAvg" | "getMin" | "getMax" | "getCount" | "stream" | "chunk" | "paginate" | "paginateWithCursor" | "exists">;
4065
- type DryModelQueryBuilderWithoutReadOperations<T extends Model, A extends Record<string, any> = {}, R extends Record<string, any> = {}> = Omit<DryModelQueryBuilder<T, A, R>, "many" | "one" | "oneOrFail" | "first" | "firstOrFail" | "paginate" | "paginateWithCursor" | "exists" | "pluck" | "upsert" | "upsertMany" | "increment" | "decrement" | "getSum" | "getAvg" | "getMin" | "getMax" | "getCount" | "stream" | "chunk" | "paginate" | "paginateWithCursor" | "exists">;
4171
+ type DryQueryBuilderWithoutReadOperations = Omit<DryQueryBuilder, "many" | "one" | "oneOrFail" | "paginate" | "paginateWithCursor" | "exists" | "pluck" | "increment" | "decrement" | "getSum" | "getAvg" | "getMin" | "getMax" | "getCount" | "stream" | "chunk" | "paginate" | "paginateWithCursor" | "exists">;
4172
+ type DryModelQueryBuilderWithoutReadOperations<T extends Model, A extends Record<string, any> = {}, R extends Record<string, any> = {}> = Omit<DryModelQueryBuilder<T, A, R>, "many" | "one" | "oneOrFail" | "paginate" | "paginateWithCursor" | "exists" | "pluck" | "upsert" | "upsertMany" | "increment" | "decrement" | "getSum" | "getAvg" | "getMin" | "getMax" | "getCount" | "stream" | "chunk" | "paginate" | "paginateWithCursor" | "exists">;
4066
4173
  type WriteQueryParam$1 = string | number | boolean | Date | RawNode | object | null | undefined;
4174
+ /**
4175
+ * Simple paginated data type for raw query builders (without Model constraint)
4176
+ */
4177
+ type RawPaginatedData<S extends Record<string, any>> = {
4178
+ paginationMetadata: {
4179
+ perPage: number;
4180
+ currentPage: number;
4181
+ firstPage: number;
4182
+ isEmpty: boolean;
4183
+ total: number;
4184
+ lastPage: number;
4185
+ hasMorePages: boolean;
4186
+ hasPages: boolean;
4187
+ };
4188
+ data: S[];
4189
+ };
4190
+ /**
4191
+ * Simple cursor paginated data type for raw query builders (without Model constraint)
4192
+ */
4193
+ type RawCursorPaginatedData<S extends Record<string, any>> = {
4194
+ paginationMetadata: {
4195
+ perPage: number;
4196
+ firstPage: number;
4197
+ isEmpty: boolean;
4198
+ total: number;
4199
+ };
4200
+ data: S[];
4201
+ };
4067
4202
 
4068
4203
  declare class SqlModelManagerUtils<T extends Model> {
4069
4204
  protected dbType: SqlDataSourceType;
@@ -4074,6 +4209,31 @@ declare class SqlModelManagerUtils<T extends Model> {
4074
4209
  getRelationFromModel(relation: ModelRelation<T>): Relation;
4075
4210
  }
4076
4211
 
4212
+ type PaginationMetadata = {
4213
+ perPage: number;
4214
+ currentPage: number;
4215
+ firstPage: number;
4216
+ isEmpty: boolean;
4217
+ total: number;
4218
+ lastPage: number;
4219
+ hasMorePages: boolean;
4220
+ hasPages: boolean;
4221
+ };
4222
+ type CursorPaginationMetadata = {
4223
+ perPage: number;
4224
+ firstPage: number;
4225
+ isEmpty: boolean;
4226
+ total: number;
4227
+ };
4228
+ type PaginatedData<T extends Model, S extends Record<string, any> = {}, R extends Record<string, any> = {}> = {
4229
+ paginationMetadata: PaginationMetadata;
4230
+ data: ([keyof S] extends [never] ? T & R : SelectedModel<T, S, R>)[];
4231
+ };
4232
+ type CursorPaginatedData<T extends Model, S extends Record<string, any> = {}, R extends Record<string, any> = {}> = {
4233
+ paginationMetadata: CursorPaginationMetadata;
4234
+ data: ([keyof S] extends [never] ? T & R : SelectedModel<T, S, R>)[];
4235
+ };
4236
+
4077
4237
  type UpdateOptions = {
4078
4238
  ignoreBeforeUpdateHook?: boolean;
4079
4239
  };
@@ -4081,7 +4241,7 @@ type UpdateOptions = {
4081
4241
  /**
4082
4242
  * @description Due to query limitations some query builder methods may not be available in a RelationQueryBuilder
4083
4243
  */
4084
- type RelationQueryBuilderType<T extends Model, A extends Record<string, any> = {}, R extends Record<string, any> = {}> = Omit<ModelQueryBuilder<T, A, R>, "increment" | "decrement" | "first" | "firstOrFail" | "paginate" | "pluck" | "truncate" | "many" | "one" | "oneOrFail" | "insert" | "insertMany" | "update" | "delete" | "softDelete" | "getSum" | "getAvg" | "getMin" | "getMax" | "getCount" | "getMin" | "getMax" | "getCount">;
4244
+ type RelationQueryBuilderType<T extends Model, A extends Record<string, any> = {}, R extends Record<string, any> = {}> = Omit<ModelQueryBuilder<T, A, R>, "increment" | "decrement" | "paginate" | "pluck" | "truncate" | "many" | "one" | "oneOrFail" | "insert" | "insertMany" | "update" | "delete" | "softDelete" | "getSum" | "getAvg" | "getMin" | "getMax" | "getCount" | "getMin" | "getMax" | "getCount">;
4085
4245
 
4086
4246
  declare class ModelQueryBuilder<T extends Model, S extends Record<string, any> = ModelWithoutRelations<T>, R extends Record<string, any> = {}> extends QueryBuilder<T> {
4087
4247
  relation: Relation;
@@ -4094,15 +4254,15 @@ declare class ModelQueryBuilder<T extends Model, S extends Record<string, any> =
4094
4254
  protected offsetValue?: number;
4095
4255
  performance: {
4096
4256
  many: (options?: ManyOptions, returnType?: "millis" | "seconds") => Promise<{
4097
- data: SelectedModel<S, R>[];
4257
+ data: SelectedModel<T, S, R>[];
4098
4258
  time: number;
4099
4259
  }>;
4100
4260
  one: (options?: OneOptions, returnType?: "millis" | "seconds") => Promise<{
4101
- data: SelectedModel<S, R> | null;
4261
+ data: SelectedModel<T, S, R> | null;
4102
4262
  time: number;
4103
4263
  }>;
4104
4264
  oneOrFail: (options?: OneOptions, returnType?: "millis" | "seconds") => Promise<{
4105
- data: SelectedModel<S, R>;
4265
+ data: SelectedModel<T, S, R>;
4106
4266
  time: number;
4107
4267
  }>;
4108
4268
  paginate: (page: number, perPage: number, options?: {
@@ -4150,20 +4310,15 @@ declare class ModelQueryBuilder<T extends Model, S extends Record<string, any> =
4150
4310
  * @description Creates a new ModelQueryBuilder instance from a model. Will use the main connection to the database by default.
4151
4311
  */
4152
4312
  static from(model: typeof Model, options?: BaseModelMethodOptions): ModelQueryBuilder<InstanceType<typeof model>>;
4153
- one(options?: OneOptions): Promise<SelectedModel<S, R> | null>;
4313
+ one(options?: OneOptions): Promise<SelectedModel<T, S, R> | null>;
4154
4314
  oneOrFail(options?: {
4155
4315
  ignoreHooks?: OneOptions["ignoreHooks"] & {
4156
4316
  customError?: Error;
4157
4317
  };
4158
- }): Promise<SelectedModel<S, R>>;
4159
- firstOrFail(options?: {
4160
- ignoreHooks?: OneOptions["ignoreHooks"] & {
4161
- customError?: Error;
4162
- };
4163
- }): Promise<SelectedModel<S, R>>;
4164
- many(options?: ManyOptions): Promise<SelectedModel<S, R>[]>;
4165
- chunk(chunkSize: number, options?: ManyOptions): AsyncGenerator<SelectedModel<S, R>[]>;
4166
- stream(options?: ManyOptions & StreamOptions): Promise<PassThrough & AsyncGenerator<SelectedModel<S, R>>>;
4318
+ }): Promise<SelectedModel<T, S, R>>;
4319
+ many(options?: ManyOptions): Promise<SelectedModel<T, S, R>[]>;
4320
+ chunk(chunkSize: number, options?: ManyOptions): AsyncGenerator<SelectedModel<T, S, R>[] | T[]>;
4321
+ stream(options?: ManyOptions & StreamOptions): Promise<PassThrough & AsyncGenerator<SelectedModel<T, S, R> | T>>;
4167
4322
  paginateWithCursor<K extends ModelKey<T>>(page: number, options?: PaginateWithCursorOptions<T, K>, cursor?: Cursor<T, K>): Promise<[CursorPaginatedData<T, S, R>, Cursor<T, K>]>;
4168
4323
  /**
4169
4324
  * @description Inserts a new record into the database, it is not advised to use this method directly from the query builder if using a ModelQueryBuilder (`Model.query()`), use the `Model.insert` method instead.
@@ -4196,21 +4351,22 @@ declare class ModelQueryBuilder<T extends Model, S extends Record<string, any> =
4196
4351
  }): Promise<PaginatedData<T, S, R>>;
4197
4352
  /**
4198
4353
  * @description Adds columns to the SELECT clause with full type safety.
4199
- * @description Supports formats: "column", "table.column", "column as alias", "*", "table.*"
4354
+ * @description Supports formats: "column", "table.column", "*", "table.*", or [column, alias] tuples
4200
4355
  * @description When columns are selected, the return type reflects only those columns
4356
+ * @warning This only allows selecting columns that are part of the model. For other columns, use `selectRaw`.
4201
4357
  * @example
4202
4358
  * ```ts
4203
4359
  * // Select specific columns - return type is { id: number, name: string }
4204
4360
  * const users = await User.query().select("id", "name").many();
4205
4361
  *
4206
- * // Select with alias - return type includes the alias
4207
- * const users = await User.query().select("id as userId").many();
4362
+ * // Select with alias using tuple - return type includes the alias
4363
+ * const users = await User.query().select(["id", "userId"]).many();
4208
4364
  *
4209
4365
  * // Select all - return type is the full model
4210
4366
  * const users = await User.query().select("*").many();
4211
4367
  * ```
4212
4368
  */
4213
- select<Columns extends readonly SelectableColumn<T>[]>(...columns: Columns): ModelQueryBuilder<T, ComposeBuildSelect<S, T, Columns extends readonly string[] ? Columns : readonly string[]>, R>;
4369
+ select<const Columns extends readonly ModelSelectableInput<T>[]>(...columns: Columns): ModelQueryBuilder<T, ComposeBuildSelect<S, T, Columns extends readonly (string | readonly [string, string])[] ? Columns : readonly (string | readonly [string, string])[]>, R>;
4214
4370
  /**
4215
4371
  * @description Adds a raw SELECT statement with type-safe return type.
4216
4372
  * @description Use the generic parameter to specify the type of the selected columns.
@@ -4231,6 +4387,30 @@ declare class ModelQueryBuilder<T extends Model, S extends Record<string, any> =
4231
4387
  * ```
4232
4388
  */
4233
4389
  selectRaw<Added extends Record<string, any> = Record<string, any>>(statement: string): ModelQueryBuilder<T, ComposeSelect<S, Added>, R>;
4390
+ /**
4391
+ * @description Selects a SQL function applied to a column with a typed alias.
4392
+ * @description Provides intellisense for common SQL functions while accepting any custom function.
4393
+ * @description Return type is auto-inferred based on function name (number for count/sum/avg, string for upper/lower/trim, etc.)
4394
+ * @param sqlFunc The SQL function name (count, sum, avg, min, max, upper, lower, etc.)
4395
+ * @param column The column to apply the function to (use "*" for count(*))
4396
+ * @param alias The alias for the result
4397
+ * @example
4398
+ * ```ts
4399
+ * const users = await User.query()
4400
+ * .selectFunc("count", "*", "total")
4401
+ * .many();
4402
+ * // users[0].total is typed as number - auto-inferred!
4403
+ *
4404
+ * const users = await User.query()
4405
+ * .select("id")
4406
+ * .selectFunc("upper", "name", "upperName")
4407
+ * .many();
4408
+ * // users[0] is { id: number, upperName: string } - auto-inferred!
4409
+ * ```
4410
+ */
4411
+ selectFunc<F extends SqlFunction, Alias extends string>(sqlFunc: F, column: ModelKey<T> | "*" | (string & {}), alias: Alias): ModelQueryBuilder<T, ComposeSelect<S, {
4412
+ [K in Alias]: SqlFunctionReturnType<F>;
4413
+ }>, R>;
4234
4414
  /**
4235
4415
  * @description Selects a subquery with a typed alias
4236
4416
  * @param cbOrQueryBuilder A callback that receives a QueryBuilder or a QueryBuilder instance
@@ -4456,90 +4636,6 @@ declare class ModelQueryBuilder<T extends Model, S extends Record<string, any> =
4456
4636
  selectJsonRaw<ValueType = any, Alias extends string = string>(raw: string, alias: Alias): ModelQueryBuilder<T, ComposeSelect<S, {
4457
4637
  [K in Alias]: ValueType;
4458
4638
  }>, R>;
4459
- /**
4460
- * @description Selects COUNT(column) with a typed alias
4461
- * @param column The column to count (use "*" for COUNT(*), supports "table.column" format)
4462
- * @param alias The alias for the count result
4463
- * @example
4464
- * ```ts
4465
- * // Count all rows
4466
- * const result = await User.query().selectCount("*", "totalUsers").one();
4467
- * console.log(result?.totalUsers); // Typed as number
4468
- *
4469
- * // Count specific column
4470
- * const result = await User.query().selectCount("id", "userCount").one();
4471
- *
4472
- * // With table prefix
4473
- * const result = await User.query().selectCount("users.id", "total").one();
4474
- * ```
4475
- */
4476
- selectCount<Alias extends string>(column: ModelKey<T> | "*" | string, alias: Alias): ModelQueryBuilder<T, ComposeSelect<S, {
4477
- [K in Alias]: number;
4478
- }>, R>;
4479
- /**
4480
- * @description Selects SUM(column) with a typed alias
4481
- * @param column The column to sum (supports "table.column" format)
4482
- * @param alias The alias for the sum result
4483
- * @example
4484
- * ```ts
4485
- * const result = await Order.query().selectSum("amount", "totalAmount").one();
4486
- * console.log(result?.totalAmount); // Typed as number
4487
- *
4488
- * // With table prefix
4489
- * const result = await Order.query().selectSum("orders.amount", "total").one();
4490
- * ```
4491
- */
4492
- selectSum<Alias extends string>(column: ModelKey<T> | string, alias: Alias): ModelQueryBuilder<T, ComposeSelect<S, {
4493
- [K in Alias]: number;
4494
- }>, R>;
4495
- /**
4496
- * @description Selects AVG(column) with a typed alias
4497
- * @param column The column to average (supports "table.column" format)
4498
- * @param alias The alias for the average result
4499
- * @example
4500
- * ```ts
4501
- * const result = await User.query().selectAvg("age", "averageAge").one();
4502
- * console.log(result?.averageAge); // Typed as number
4503
- *
4504
- * // With table prefix
4505
- * const result = await User.query().selectAvg("users.age", "avgAge").one();
4506
- * ```
4507
- */
4508
- selectAvg<Alias extends string>(column: ModelKey<T> | string, alias: Alias): ModelQueryBuilder<T, ComposeSelect<S, {
4509
- [K in Alias]: number;
4510
- }>, R>;
4511
- /**
4512
- * @description Selects MIN(column) with a typed alias
4513
- * @param column The column to get minimum value (supports "table.column" format)
4514
- * @param alias The alias for the min result
4515
- * @example
4516
- * ```ts
4517
- * const result = await User.query().selectMin("age", "youngestAge").one();
4518
- * console.log(result?.youngestAge); // Typed as number
4519
- *
4520
- * // With table prefix
4521
- * const result = await User.query().selectMin("users.age", "minAge").one();
4522
- * ```
4523
- */
4524
- selectMin<Alias extends string>(column: ModelKey<T> | string, alias: Alias): ModelQueryBuilder<T, ComposeSelect<S, {
4525
- [K in Alias]: number;
4526
- }>, R>;
4527
- /**
4528
- * @description Selects MAX(column) with a typed alias
4529
- * @param column The column to get maximum value (supports "table.column" format)
4530
- * @param alias The alias for the max result
4531
- * @example
4532
- * ```ts
4533
- * const result = await User.query().selectMax("age", "oldestAge").one();
4534
- * console.log(result?.oldestAge); // Typed as number
4535
- *
4536
- * // With table prefix
4537
- * const result = await User.query().selectMax("users.age", "maxAge").one();
4538
- * ```
4539
- */
4540
- selectMax<Alias extends string>(column: ModelKey<T> | string, alias: Alias): ModelQueryBuilder<T, ComposeSelect<S, {
4541
- [K in Alias]: number;
4542
- }>, R>;
4543
4639
  /**
4544
4640
  * @description Fills the relations in the model in the serialized response. Relation must be defined in the model.
4545
4641
  * @warning Many to many relations have special behavior, since they require a join, a join clause will always be added to the query.
@@ -4602,8 +4698,8 @@ declare class ModelQueryBuilder<T extends Model, S extends Record<string, any> =
4602
4698
  * @description Recursively processes all relations, including nested ones
4603
4699
  */
4604
4700
  protected processRelationsRecursively(models: T[]): Promise<void>;
4605
- protected mapRelatedModelsToModels<R extends ModelWithoutRelations<T>>(relation: Relation, modelsToFillWithRelations: T[], relatedModels: R[]): void;
4606
- protected getRelatedModelsForRelation(relationQueryBuilder: ModelQueryBuilder<any>, relation: Relation, models: T[]): Promise<ModelWithoutRelations<T>[]>;
4701
+ protected mapRelatedModelsToModels<R extends SelectedModel<T, ModelWithoutRelations<T>, Record<string, any>>>(relation: Relation, modelsToFillWithRelations: T[], relatedModels: R[]): void;
4702
+ protected getRelatedModelsForRelation(relationQueryBuilder: ModelQueryBuilder<any>, relation: Relation, models: T[]): Promise<SelectedModel<T, ModelWithoutRelations<T>, R>[]>;
4607
4703
  protected getRelatedModelsQueryForRelation(relationQueryBuilder: ModelQueryBuilder<any>, relation: Relation, models: T[]): ModelQueryBuilder<any, any, any>;
4608
4704
  protected getFilterValuesFromModelsForRelation(relation: Relation, models: T[]): any[];
4609
4705
  protected applyHavingRelatedFilter(relationQueryBuilder: ModelQueryBuilder<any>, relation: Relation, operator?: BinaryOperatorType, value?: BaseValues): void;
@@ -5123,13 +5219,29 @@ declare class SqlDataSource<D extends SqlDataSourceType = SqlDataSourceType, T e
5123
5219
  */
5124
5220
  dryQuery<S extends string>(table: TableFormat<S>, options?: RawModelOptions): DryQueryBuilderWithoutReadOperations;
5125
5221
  /**
5126
- * @description Return the query to alter the given table schema
5127
- */
5128
- alterTable(...args: Parameters<Schema["alterTable"]>): string[];
5129
- /**
5130
- * @description Return the query to create the given table schema
5222
+ * @description Returns a SchemaBuilder instance for DDL operations
5223
+ * @description The builder will execute queries when awaited or when .execute() is called
5224
+ * @description Use .toQuery() or .toString() to get the SQL without executing
5225
+ * @example
5226
+ * ```ts
5227
+ * // Execute on await
5228
+ * await sql.schema().createTable("users", (table) => {
5229
+ * table.addColumn("id", "integer", { primaryKey: true });
5230
+ * });
5231
+ *
5232
+ * // Get SQL without executing
5233
+ * const sql = sql.schema().createTable("users", (table) => {
5234
+ * table.addColumn("id", "integer", { primaryKey: true });
5235
+ * }).toQuery();
5236
+ *
5237
+ * // Multiple operations
5238
+ * const builder = sql.schema();
5239
+ * builder.createTable("users", (table) => { ... });
5240
+ * builder.createTable("posts", (table) => { ... });
5241
+ * await builder; // Executes all
5242
+ * ```
5131
5243
  */
5132
- createTable(...args: Parameters<Schema["createTable"]>): string;
5244
+ schema(): SchemaBuilder;
5133
5245
  /**
5134
5246
  * @description Starts a global transaction on the database
5135
5247
  * @description Intended for testing purposes - wraps all operations in a transaction that can be rolled back
@@ -5290,7 +5402,130 @@ declare class SqlDataSource<D extends SqlDataSourceType = SqlDataSourceType, T e
5290
5402
  private connectWithoutSettingPrimary;
5291
5403
  }
5292
5404
 
5293
- type ModelWithoutRelations<T extends Model> = Pick<Omit<T, "*">, ExcludeRelations<Omit<T, "*">>> & Pick<Model, keyof Model>;
5405
+ /**
5406
+ * Extracts only non-method keys from a type.
5407
+ * Excludes any property that is a function.
5408
+ */
5409
+ type ExcludeMethods<T> = {
5410
+ [K in keyof T]: T[K] extends (...args: any[]) => any ? never : K;
5411
+ }[keyof T];
5412
+ /**
5413
+ * Picks only non-method properties from the base Model class.
5414
+ * This ensures that when selecting specific columns, instance methods
5415
+ * like save(), delete(), refresh() are not incorrectly included.
5416
+ */
5417
+ type ModelDataProperties = Pick<Model, ExcludeMethods<Model>>;
5418
+ /**
5419
+ * Model instance methods available on query results.
5420
+ * These methods enable CRUD operations on fetched models.
5421
+ *
5422
+ * All query results from Model static methods (find, findOne, findOneOrFail,
5423
+ * findBy, findOneBy, findOneByPrimaryKey, all, first, insert, insertMany,
5424
+ * upsert, upsertMany, updateRecord, softDelete) and from ModelQueryBuilder
5425
+ * (one, many, oneOrFail) include these instance methods.
5426
+ *
5427
+ * @example
5428
+ * ```typescript
5429
+ * // Using instance methods on query results
5430
+ * const user = await User.findOne({ where: { email: "test@example.com" } });
5431
+ * if (user) {
5432
+ * user.mergeProps({ name: "Updated Name" });
5433
+ * await user.save();
5434
+ *
5435
+ * // Or update directly
5436
+ * await user.update({ name: "Another Name" });
5437
+ *
5438
+ * // Refresh from database
5439
+ * await user.refresh();
5440
+ *
5441
+ * // Soft delete or hard delete
5442
+ * await user.softDelete();
5443
+ * // or: await user.delete();
5444
+ * }
5445
+ *
5446
+ * // Works with query builder too
5447
+ * const user2 = await User.query().where("id", 1).oneOrFail();
5448
+ * await user2.update({ status: "inactive" });
5449
+ *
5450
+ * // Works with select projections
5451
+ * const user3 = await User.query().select("id", "name").one();
5452
+ * if (user3) {
5453
+ * await user3.delete(); // Still has access to instance methods
5454
+ * }
5455
+ * ```
5456
+ *
5457
+ * Note: These signatures are simplified versions that don't carry the
5458
+ * `this: T extends Model` constraint, allowing them to work on selected
5459
+ * model results without requiring full Model type compatibility.
5460
+ */
5461
+ type ModelInstanceMethods<T extends Model> = {
5462
+ /**
5463
+ * Merges the provided data with the model instance.
5464
+ * Does not persist to database - use save() or update() after merging.
5465
+ */
5466
+ mergeProps: (data: Partial<ModelWithoutRelations<T>>) => void;
5467
+ /**
5468
+ * Saves the model to the database (insert or update based on primary key).
5469
+ * @throws {HysteriaError} If the model has no primary key defined
5470
+ */
5471
+ save: (options?: Omit<BaseModelMethodOptions, "ignoreHooks">) => Promise<any>;
5472
+ /**
5473
+ * Updates the model in the database with the provided payload.
5474
+ * @throws {HysteriaError} If the model has no primary key or primary key value
5475
+ */
5476
+ update: (payload: Partial<ModelWithoutRelations<T>>, options?: Omit<BaseModelMethodOptions, "ignoreHooks">) => Promise<void>;
5477
+ /**
5478
+ * Soft deletes the model by setting the soft delete column.
5479
+ * @throws {HysteriaError} If the model has no primary key or primary key value
5480
+ */
5481
+ softDelete: (softDeleteOptions?: {
5482
+ column?: string;
5483
+ value?: string | number | boolean | Date;
5484
+ }, options?: Omit<BaseModelMethodOptions, "ignoreHooks">) => Promise<void>;
5485
+ /**
5486
+ * Hard deletes the model from the database.
5487
+ * @throws {HysteriaError} If the model has no primary key or primary key value
5488
+ */
5489
+ delete: (options?: Omit<BaseModelMethodOptions, "ignoreHooks">) => Promise<void>;
5490
+ /**
5491
+ * Refreshes the model from the database, updating all properties with current values.
5492
+ * @throws {HysteriaError} If the model has no primary key or primary key value
5493
+ */
5494
+ refresh: (options?: Omit<BaseModelMethodOptions, "ignoreHooks">) => Promise<any>;
5495
+ };
5496
+ /**
5497
+ * Model data without relation properties.
5498
+ * Includes only data columns from the model, excluding foreign keys and relation accessors.
5499
+ */
5500
+ type ModelWithoutRelations<T extends Model> = Pick<Omit<T, "*">, ExcludeRelations<Omit<T, "*">>> & ModelDataProperties;
5501
+ /**
5502
+ * Return type for Model query/mutation methods.
5503
+ * Combines data properties with instance methods for CRUD operations.
5504
+ *
5505
+ * This type is used as the return type for:
5506
+ * - Static find methods: find, findOne, findOneOrFail, findBy, findOneBy, findOneByPrimaryKey
5507
+ * - Static retrieval methods: all, first
5508
+ * - Static mutation methods: insert, insertMany, upsert, upsertMany, updateRecord, softDelete
5509
+ * - Static refresh method: refresh
5510
+ *
5511
+ * @example
5512
+ * ```typescript
5513
+ * // All these methods return ModelQueryResult<User> (or arrays/nullables thereof)
5514
+ * const user1 = await User.findOne({ where: { id: 1 } });
5515
+ * const user2 = await User.findOneOrFail({ where: { id: 1 } });
5516
+ * const users = await User.find({});
5517
+ * const allUsers = await User.all();
5518
+ * const newUser = await User.insert({ name: "John" });
5519
+ *
5520
+ * // Each result has instance methods available
5521
+ * if (user1) {
5522
+ * await user1.update({ name: "Jane" });
5523
+ * await user1.refresh();
5524
+ * await user1.delete();
5525
+ * }
5526
+ * ```
5527
+ */
5528
+ type ModelQueryResult<T extends Model> = ModelWithoutRelations<T> & ModelInstanceMethods<T>;
5294
5529
  type NumberModelKey<T extends Model> = {
5295
5530
  [K in keyof T]: T[K] extends number | bigint ? K : never;
5296
5531
  }[keyof T];
@@ -5389,7 +5624,9 @@ type RelatedInstance<M extends Model, K extends ModelRelation<M>> = NonNullable<
5389
5624
  */
5390
5625
  type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
5391
5626
  /**
5392
- * Represents all valid column selection formats with intellisense support.
5627
+ * Represents valid string column selection formats with intellisense support.
5628
+ * Use [column, alias] tuple format for aliases instead of "column as alias".
5629
+ * Use selectFunction() for SQL functions instead of embedding them in select().
5393
5630
  *
5394
5631
  * ## Supported Formats
5395
5632
  *
@@ -5397,7 +5634,6 @@ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
5397
5634
  * |---------------------------|--------------------------|--------------------------------|
5398
5635
  * | Model column | `"name"` | Direct column with intellisense |
5399
5636
  * | Qualified column | `"users.name"` | Table-prefixed column |
5400
- * | Aliased column | `"name as userName"` | Column with custom alias |
5401
5637
  * | Wildcard | `"*"` | Select all from primary table |
5402
5638
  * | Table wildcard | `"users.*"` | Select all from specific table |
5403
5639
  *
@@ -5405,17 +5641,32 @@ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
5405
5641
  * User.query().select(
5406
5642
  * "name", // Model column with intellisense
5407
5643
  * "users.email", // Qualified column
5408
- * "age as userAge", // Aliased column
5409
5644
  * "*" // All columns
5410
5645
  * );
5411
5646
  */
5412
- type SelectableColumn<T extends Model> = ModelKey<T> | `${string}.${string}` | `${string} as ${string}` | `${string}(${string}) as ${string}` | "*";
5647
+ type SelectableColumn<T extends Model> = ModelKey<T> | `${string}.${string | "*"}` | "*";
5648
+ /**
5649
+ * A tuple type for selecting a column with an alias in ModelQueryBuilder.
5650
+ * @example ["id", "userId"] selects "id" column as "userId"
5651
+ */
5652
+ type ModelSelectTuple<T extends Model, C extends ModelKey<T> | `${string}.${string}` = ModelKey<T> | `${string}.${string}`, A extends string = string> = readonly [column: C, alias: A];
5413
5653
  /**
5414
- * Extracts the final property name from a column selection string.
5654
+ * Input type for select() method in ModelQueryBuilder.
5655
+ * Accepts either a column string or a [column, alias] tuple for aliasing.
5656
+ *
5657
+ * @example
5658
+ * .select("id", "name") // Simple columns
5659
+ * .select(["id", "userId"], ["name", "userName"]) // Columns with aliases
5660
+ * .select("id", ["name", "userName"]) // Mixed
5661
+ */
5662
+ type ModelSelectableInput<T extends Model> = SelectableColumn<T> | ModelSelectTuple<T>;
5663
+ /**
5664
+ * Extracts the final property name from a column selection.
5665
+ * Supports both string columns and [column, alias] tuples.
5415
5666
  *
5416
5667
  * This type determines what property name will be available on the result:
5417
5668
  * - Plain columns use their name directly
5418
- * - Aliased columns use the alias
5669
+ * - Tuples use the alias (second element)
5419
5670
  * - Wildcards return `never` (handled specially to return full model)
5420
5671
  *
5421
5672
  * ## Extraction Rules
@@ -5424,12 +5675,26 @@ type SelectableColumn<T extends Model> = ModelKey<T> | `${string}.${string}` | `
5424
5675
  * |--------------------------|---------------|--------------------------------|
5425
5676
  * | `"name"` | `"name"` | Direct column |
5426
5677
  * | `"users.name"` | `"name"` | Extract column from qualified |
5427
- * | `"name as userName"` | `"userName"` | Use alias |
5428
- * | `"users.name as author"` | `"author"` | Alias takes precedence |
5678
+ * | `["name", "userName"]` | `"userName"` | Use alias from tuple |
5679
+ * | `["users.id", "id"]` | `"id"` | Use alias from tuple |
5429
5680
  * | `"*"` | `never` | Wildcard - full model |
5430
5681
  * | `"users.*"` | `never` | Table wildcard - Record<> |
5431
5682
  */
5432
- type ExtractColumnName<S extends string> = S extends `${string} as ${infer Alias}` ? Alias : S extends "*" ? never : S extends `${string}.*` ? never : S extends `${string}.${infer Column}` ? Column extends "*" ? never : Column : S;
5683
+ type ExtractColumnName<S> = S extends readonly [
5684
+ string,
5685
+ infer Alias extends string
5686
+ ] ? Alias : S extends string ? S extends "*" ? never : S extends `${string}.*` ? never : S extends `${string}.${infer Column}` ? Column extends "*" ? never : Column : S : never;
5687
+ /**
5688
+ * Extracts the source column name from a selectable input.
5689
+ * For strings, returns the column part (after last dot if qualified).
5690
+ * For tuples, returns the first element (the column).
5691
+ *
5692
+ * @internal
5693
+ */
5694
+ type ExtractSourceColumn<S> = S extends readonly [
5695
+ infer Column extends string,
5696
+ string
5697
+ ] ? Column extends `${string}.${infer Col}` ? Col : Column : S extends string ? S extends `${string}.${infer Column}` ? Column : S : never;
5433
5698
  /**
5434
5699
  * Resolves the TypeScript type for a selected column.
5435
5700
  *
@@ -5444,28 +5709,34 @@ type ExtractColumnName<S extends string> = S extends `${string} as ${infer Alias
5444
5709
  type GetColumnType<T extends Model, ColumnName extends string> = ColumnName extends keyof ModelWithoutRelations<T> ? ModelWithoutRelations<T>[ColumnName] : any;
5445
5710
  /**
5446
5711
  * Builds the type for a single selected column.
5712
+ * Supports both string columns and [column, alias] tuples.
5447
5713
  *
5448
5714
  * ## Type Resolution
5449
5715
  *
5450
- * | Selection | Result Type |
5451
- * |--------------------|---------------------------------------|
5452
- * | `"*"` | `ModelWithoutRelations<T>` (full) |
5453
- * | `"table.*"` | `Record<string, any>` (unknown shape) |
5454
- * | `"column"` | `{ column: ColumnType }` |
5455
- * | `"col as alias"` | `{ alias: ColumnType }` |
5716
+ * | Selection | Result Type |
5717
+ * |------------------------|---------------------------------------|
5718
+ * | `"*"` | `ModelWithoutRelations<T>` (full) |
5719
+ * | `"table.*"` | `Record<string, any>` (unknown shape) |
5720
+ * | `"column"` | `{ column: ColumnType }` |
5721
+ * | `["col", "alias"]` | `{ alias: ColumnType }` |
5456
5722
  *
5457
5723
  * @internal
5458
5724
  */
5459
- type BuildSingleSelectType<T extends Model, S extends string> = S extends "*" ? ModelWithoutRelations<T> : S extends `${string}.*` ? Record<string, any> : ExtractColumnName<S> extends never ? {} : {
5460
- [K in ExtractColumnName<S>]: GetColumnType<T, ExtractColumnName<S>>;
5461
- };
5725
+ type BuildSingleSelectType<T extends Model, S> = S extends readonly [
5726
+ infer Column extends string,
5727
+ infer Alias extends string
5728
+ ] ? {
5729
+ [K in Alias]: GetColumnType<T, ExtractSourceColumn<S> & string>;
5730
+ } : S extends string ? S extends "*" ? ModelWithoutRelations<T> : S extends `${string}.*` ? Record<string, any> : ExtractColumnName<S> extends never ? {} : {
5731
+ [K in ExtractColumnName<S> & string]: GetColumnType<T, ExtractColumnName<S> & string>;
5732
+ } : {};
5462
5733
  /**
5463
5734
  * Checks if a column selection includes wildcards or is empty.
5464
5735
  * Used to determine if the full model type should be returned.
5465
5736
  *
5466
5737
  * @internal
5467
5738
  */
5468
- type HasStarOrEmpty<Columns extends readonly string[]> = Columns["length"] extends 0 ? true : "*" extends Columns[number] ? true : false;
5739
+ type HasStarOrEmpty<Columns extends readonly (string | readonly [string, string])[]> = Columns["length"] extends 0 ? true : "*" extends Columns[number] ? true : false;
5469
5740
  /**
5470
5741
  * Unique symbol used internally to mark that a select() has been called.
5471
5742
  */
@@ -5483,6 +5754,7 @@ type SelectBrand = {
5483
5754
  };
5484
5755
  /**
5485
5756
  * Builds the combined TypeScript type for multiple selected columns.
5757
+ * Supports both string columns and [column, alias] tuples.
5486
5758
  *
5487
5759
  * This is the main type used to compute the return type of `select()` calls.
5488
5760
  * It handles all the complexity of combining multiple column selections into
@@ -5496,8 +5768,8 @@ type SelectBrand = {
5496
5768
  * 4. **Always includes**: Base `Model` methods (save, delete, etc.)
5497
5769
  *
5498
5770
  * @example
5499
- * // .select("name", "age as userAge")
5500
- * BuildSelectType<User, ["name", "age as userAge"]>
5771
+ * // .select("name", ["age", "userAge"])
5772
+ * BuildSelectType<User, ["name", ["age", "userAge"]]>
5501
5773
  * // Result: { name: string; userAge: number } & Pick<Model, keyof Model>
5502
5774
  *
5503
5775
  * @example
@@ -5505,9 +5777,9 @@ type SelectBrand = {
5505
5777
  * BuildSelectType<User, ["*"]>
5506
5778
  * // Result: ModelWithoutRelations<User> (all columns)
5507
5779
  */
5508
- type BuildSelectType<T extends Model, Columns extends readonly string[]> = HasStarOrEmpty<Columns> extends true ? ModelWithoutRelations<T> : UnionToIntersection<{
5509
- [K in keyof Columns]: Columns[K] extends string ? BuildSingleSelectType<T, Columns[K]> : {};
5510
- }[number]> extends infer Result ? Result extends Record<string, any> ? keyof Result extends never ? ModelWithoutRelations<T> : Result & Pick<Model, keyof Model> & SelectBrand : ModelWithoutRelations<T> : ModelWithoutRelations<T>;
5780
+ type BuildSelectType<T extends Model, Columns extends readonly (string | readonly [string, string])[]> = HasStarOrEmpty<Columns> extends true ? ModelWithoutRelations<T> : UnionToIntersection<{
5781
+ [K in keyof Columns]: BuildSingleSelectType<T, Columns[K]>;
5782
+ }[number]> extends infer Result ? Result extends Record<string, any> ? keyof Result extends never ? ModelWithoutRelations<T> : Result & ModelDataProperties & SelectBrand : ModelWithoutRelations<T> : ModelWithoutRelations<T>;
5511
5783
  /**
5512
5784
  * Composes a new selection with the existing selection state.
5513
5785
  *
@@ -5530,9 +5802,10 @@ type BuildSelectType<T extends Model, Columns extends readonly string[]> = HasSt
5530
5802
  * ComposeSelect<{ count: number } & Pick<Model, keyof Model> & SelectBrand, { userName: string }>
5531
5803
  * // Result: { count: number } & Pick<Model, keyof Model> & SelectBrand & { userName: string }
5532
5804
  */
5533
- type ComposeSelect<S extends Record<string, any>, Added extends Record<string, any>> = (typeof SELECT_BRAND extends keyof S ? S : Pick<Model, keyof Model> & SelectBrand) & Added;
5805
+ type ComposeSelect<S extends Record<string, any>, Added extends Record<string, any>> = (typeof SELECT_BRAND extends keyof S ? S : ModelDataProperties & SelectBrand) & Added;
5534
5806
  /**
5535
5807
  * Composes a BuildSelectType result with the existing selection state.
5808
+ * Supports both string columns and [column, alias] tuples.
5536
5809
  *
5537
5810
  * Similar to ComposeSelect but designed for use with BuildSelectType which already
5538
5811
  * includes Pick<Model, keyof Model> and SelectBrand in its result.
@@ -5555,21 +5828,24 @@ type ComposeSelect<S extends Record<string, any>, Added extends Record<string, a
5555
5828
  * ComposeBuildSelect<{ count: number } & Pick<Model, keyof Model> & SelectBrand, User, ["id"]>
5556
5829
  * // Result: { count: number } & Pick<Model, keyof Model> & SelectBrand & { id: number }
5557
5830
  */
5558
- type ComposeBuildSelect<S extends Record<string, any>, T extends Model, Columns extends readonly string[]> = (typeof SELECT_BRAND extends keyof S ? S : {}) & BuildSelectType<T, Columns>;
5831
+ type ComposeBuildSelect<S extends Record<string, any>, T extends Model, Columns extends readonly (string | readonly [string, string])[]> = (typeof SELECT_BRAND extends keyof S ? S : {}) & BuildSelectType<T, Columns>;
5559
5832
  /**
5560
5833
  * The final result type for ModelQueryBuilder queries.
5561
5834
  *
5562
- * Combines selected columns (S) with loaded relations (R) into a single type.
5835
+ * Combines selected columns (S) with loaded relations (R) and Model instance methods
5836
+ * into a single type. This ensures query results have access to CRUD operations
5837
+ * like save(), update(), delete(), etc.
5563
5838
  *
5839
+ * @typeParam M - The Model type
5564
5840
  * @typeParam S - Selected columns type from `select()` calls
5565
5841
  * @typeParam R - Relations type from `load()` calls
5566
5842
  *
5567
5843
  * @example
5568
5844
  * // User.query().select("name").load("posts").one()
5569
- * SelectedModel<{ name: string }, { posts: Post[] }>
5570
- * // Result: { name: string; posts: Post[] }
5845
+ * SelectedModel<User, { name: string }, { posts: Post[] }>
5846
+ * // Result: { name: string; posts: Post[] } & ModelInstanceMethods
5571
5847
  */
5572
- type SelectedModel<S extends Record<string, any> = {}, R extends Record<string, any> = {}> = S & R;
5848
+ type SelectedModel<M extends Model, S extends Record<string, any> = {}, R extends Record<string, any> = {}> = S & R & ModelInstanceMethods<M>;
5573
5849
 
5574
5850
  type NullableAndUndefinable<T> = T | (T | null) | (T | undefined) | (T | null | undefined);
5575
5851
  type UpsertOptions<T extends Model> = {
@@ -5657,7 +5933,7 @@ type FindOneType<T extends Model, S extends ModelKey<T>[] = any[], R extends Mod
5657
5933
  type FindType<T extends Model, S extends ModelKey<T>[] = any[], R extends ModelRelation<T>[] = never[]> = Omit<FindOneType<T, S, R>, "throwErrorOnNull"> & {
5658
5934
  limit?: number;
5659
5935
  };
5660
- type FindReturnType<T extends Model, S extends ModelKey<T>[] = any[], R extends ModelRelation<T>[] = never[]> = S extends readonly any[] ? S[number] extends never ? ModelWithoutRelations<T> & {
5936
+ type FindReturnType<T extends Model, S extends ModelKey<T>[] = any[], R extends ModelRelation<T>[] = never[]> = (S extends readonly any[] ? S[number] extends never ? ModelWithoutRelations<T> & {
5661
5937
  [K in R[number] & keyof T]: T[K];
5662
5938
  } : {
5663
5939
  [K in S[number] & keyof T]: T[K];
@@ -5665,7 +5941,7 @@ type FindReturnType<T extends Model, S extends ModelKey<T>[] = any[], R extends
5665
5941
  [K in R[number] & keyof T]: T[K];
5666
5942
  } : ModelWithoutRelations<T> & {
5667
5943
  [K in R[number] & keyof T]: T[K];
5668
- };
5944
+ }) & ModelInstanceMethods<T>;
5669
5945
 
5670
5946
  /**
5671
5947
  * @description Represents a Table in the Database
@@ -5701,7 +5977,7 @@ declare abstract class Model extends Entity {
5701
5977
  /**
5702
5978
  * @description Returns all the records for the given model
5703
5979
  */
5704
- static all<T extends Model>(this: new () => T | typeof Model, options?: BaseModelMethodOptions): Promise<ModelWithoutRelations<T>[]>;
5980
+ static all<T extends Model>(this: new () => T | typeof Model, options?: BaseModelMethodOptions): Promise<ModelQueryResult<T>[]>;
5705
5981
  /**
5706
5982
  * @description Gives a query sqlInstance for the given model
5707
5983
  */
@@ -5715,7 +5991,7 @@ declare abstract class Model extends Entity {
5715
5991
  * @description Finds the first record in the database
5716
5992
  * @deprecated Used only for debugging purposes, use `.findOne` or `.query` instead
5717
5993
  */
5718
- static first<T extends Model>(this: new () => T | typeof Model, options?: BaseModelMethodOptions): Promise<ModelWithoutRelations<T> | null>;
5994
+ static first<T extends Model>(this: new () => T | typeof Model, options?: BaseModelMethodOptions): Promise<ModelQueryResult<T> | null>;
5719
5995
  /**
5720
5996
  * @description Finds records for the given model
5721
5997
  */
@@ -5745,7 +6021,7 @@ declare abstract class Model extends Entity {
5745
6021
  /**
5746
6022
  * @description Refreshes a model from the database, the model must have a primary key defined
5747
6023
  */
5748
- static refresh<T extends Model>(this: new () => T | typeof Model, model: T, options?: Omit<BaseModelMethodOptions, "ignoreHooks">): Promise<ModelWithoutRelations<T> | null>;
6024
+ static refresh<T extends Model>(this: new () => T | typeof Model, model: T, options?: Omit<BaseModelMethodOptions, "ignoreHooks">): Promise<ModelQueryResult<T> | null>;
5749
6025
  /**
5750
6026
  * @description Saves a new record to the database
5751
6027
  * @warning If not using postgres and the model has no primary key, the model will be saved, but it won't be possible to retrieve it so at that point it will be returned as null, this is not typed as Model | null for type safety reasons
@@ -5753,7 +6029,7 @@ declare abstract class Model extends Entity {
5753
6029
  * @sqlite If no Primary Key is present in the model definition, the model will be returned
5754
6030
  * @sqlite Returning Not supported and won't have effect
5755
6031
  */
5756
- static insert<T extends Model>(this: new () => T | typeof Model, modelData: Partial<ModelWithoutRelations<T>>, options?: BaseModelMethodOptions & InsertOptions<T>): Promise<ModelWithoutRelations<T>>;
6032
+ static insert<T extends Model>(this: new () => T | typeof Model, modelData: Partial<ModelWithoutRelations<T>>, options?: BaseModelMethodOptions & InsertOptions<T>): Promise<ModelQueryResult<T>>;
5757
6033
  /**
5758
6034
  * @description Saves multiple records to the database
5759
6035
  * @warning If not using postgres and the model has no primary key, the models will be saved, but it won't be possible to retrieve them so at that point they will be returned as an empty array
@@ -5762,7 +6038,7 @@ declare abstract class Model extends Entity {
5762
6038
  * @sqlite Returning Not supported and won't have effect
5763
6039
  * @oracledb may do multiple inserts with auto-generated identity columns
5764
6040
  */
5765
- static insertMany<T extends Model>(this: new () => T | typeof Model, modelsData: Partial<ModelWithoutRelations<T>>[], options?: BaseModelMethodOptions & InsertOptions<T>): Promise<ModelWithoutRelations<T>[]>;
6041
+ static insertMany<T extends Model>(this: new () => T | typeof Model, modelsData: Partial<ModelWithoutRelations<T>>[], options?: BaseModelMethodOptions & InsertOptions<T>): Promise<ModelQueryResult<T>[]>;
5766
6042
  /**
5767
6043
  * @description Syncs in the through table the given models for the given relation
5768
6044
  * @param relation The many to many relation to sync, this is not type safe since many to many relations defined at a decorator level
@@ -5784,7 +6060,7 @@ declare abstract class Model extends Entity {
5784
6060
  * @description Can only be used if the model has a primary key, use a massive update if the model has no primary key
5785
6061
  * @throws {HysteriaError} If the model has no primary key
5786
6062
  */
5787
- static updateRecord<T extends Model>(this: new () => T | typeof Model, modelSqlInstance: Partial<T>, updatePayload?: Partial<ModelWithoutRelations<T>>, options?: Omit<BaseModelMethodOptions, "ignoreHooks">): Promise<ModelWithoutRelations<T>>;
6063
+ static updateRecord<T extends Model>(this: new () => T | typeof Model, modelSqlInstance: Partial<T>, updatePayload?: Partial<ModelWithoutRelations<T>>, options?: Omit<BaseModelMethodOptions, "ignoreHooks">): Promise<ModelQueryResult<T>>;
5788
6064
  /**
5789
6065
  * @description Finds the first record or creates a new one if it doesn't exist
5790
6066
  */
@@ -5797,12 +6073,12 @@ declare abstract class Model extends Entity {
5797
6073
  /**
5798
6074
  * @description Updates or creates a new record, if no searchCriteria payload is provided, provided data will be inserted as is
5799
6075
  */
5800
- static upsert<T extends Model>(this: new () => T | typeof Model, searchCriteria: Partial<ModelWithoutRelations<T>>, data: Partial<ModelWithoutRelations<T>>, options?: UpsertOptions<T> & BaseModelMethodOptions): Promise<ModelWithoutRelations<T>>;
6076
+ static upsert<T extends Model>(this: new () => T | typeof Model, searchCriteria: Partial<ModelWithoutRelations<T>>, data: Partial<ModelWithoutRelations<T>>, options?: UpsertOptions<T> & BaseModelMethodOptions): Promise<ModelQueryResult<T>>;
5801
6077
  /**
5802
6078
  * @description Updates or creates multiple records
5803
6079
  * @param {updateOnConflict} If true, the record will be updated if it exists, otherwise it will be ignored
5804
6080
  */
5805
- static upsertMany<T extends Model>(this: new () => T | typeof Model, conflictColumns: ModelKey<T>[], data: Partial<ModelWithoutRelations<T>>[], options?: UpsertOptions<T> & BaseModelMethodOptions): Promise<ModelWithoutRelations<T>[]>;
6081
+ static upsertMany<T extends Model>(this: new () => T | typeof Model, conflictColumns: ModelKey<T>[], data: Partial<ModelWithoutRelations<T>>[], options?: UpsertOptions<T> & BaseModelMethodOptions): Promise<ModelQueryResult<T>[]>;
5806
6082
  /**
5807
6083
  * @description Deletes a record to the database
5808
6084
  */
@@ -5816,7 +6092,7 @@ declare abstract class Model extends Entity {
5816
6092
  static softDelete<T extends Model>(this: new () => T | typeof Model, modelSqlInstance: T, softDeleteOptions?: {
5817
6093
  column?: ModelKey<T>;
5818
6094
  value?: string | number | boolean | Date;
5819
- }, options?: Omit<BaseModelMethodOptions, "ignoreHooks">): Promise<ModelWithoutRelations<T>>;
6095
+ }, options?: Omit<BaseModelMethodOptions, "ignoreHooks">): Promise<ModelQueryResult<T>>;
5820
6096
  /**
5821
6097
  * @description Truncates the table for the given model
5822
6098
  */
@@ -7194,6 +7470,111 @@ declare class RedisDataSource {
7194
7470
  protected static getValue<T = RedisFetchable>(value: string | null): T | null;
7195
7471
  }
7196
7472
 
7473
+ declare class Schema {
7474
+ queryStatements: string[];
7475
+ sqlType: SqlDataSourceType;
7476
+ constructor(sqlType?: SqlDataSourceType);
7477
+ /**
7478
+ * @description Adds a raw statement to define a default value as is
7479
+ * @example
7480
+ * ```ts
7481
+ * schema.rawStatement("CURRENT_TIMESTAMP");
7482
+ * schema.alterTable("users", (table) => {
7483
+ * table.timestamp("created_at").default(this.schema.rawStatement("CURRENT_TIMESTAMP"));
7484
+ * });
7485
+ * ```
7486
+ */
7487
+ rawStatement(value: string): RawNode;
7488
+ /**
7489
+ * @description Add raw query to the migration
7490
+ */
7491
+ rawQuery(query: string): void;
7492
+ /**
7493
+ * @description Executes the queries built by the schema
7494
+ */
7495
+ execute(): Promise<void>;
7496
+ /**
7497
+ * @description Runs the sql in the given file, throws error if file does not exist or is not .sql or .txt
7498
+ * @description File is splitted by semicolons and each statement is executed separately and in order
7499
+ */
7500
+ runFile(filePath: string): void;
7501
+ /**
7502
+ * @description Create table constructor
7503
+ * @mssql Does not support ifNotExists option
7504
+ */
7505
+ createTable(table: string, cb: (table: CreateTableBuilder) => void, options?: {
7506
+ ifNotExists?: boolean;
7507
+ }): void;
7508
+ /**
7509
+ * @description Alter table constructor
7510
+ * @mssql Limited support - cannot modify columns with constraints; see AlterTableBuilder methods for details
7511
+ */
7512
+ alterTable(table: string, cb: (t: AlterTableBuilder) => void): void;
7513
+ /**
7514
+ * @description Drop table in the database
7515
+ */
7516
+ dropTable(table: string, ifExists?: boolean): void;
7517
+ /**
7518
+ * @description Rename table in the database
7519
+ * @mssql Uses sp_rename procedure; does not update references in views/procedures/triggers
7520
+ */
7521
+ renameTable(oldTable: string, newTable: string): void;
7522
+ /**
7523
+ * @description Truncate table
7524
+ */
7525
+ truncateTable(table: string): void;
7526
+ /**
7527
+ * @description Create index on table
7528
+ */
7529
+ createIndex(table: string, columns: string[] | string, options?: CommonConstraintOptions): void;
7530
+ /**
7531
+ * @description Drop index on table
7532
+ * @mysql requires table name for index drop
7533
+ */
7534
+ dropIndex(indexName: string, table?: string): void;
7535
+ /**
7536
+ * @description Adds a primary key to a table
7537
+ */
7538
+ addPrimaryKey(table: string, columns: string[]): void;
7539
+ /**
7540
+ * @description Adds a UNIQUE constraint to a table
7541
+ */
7542
+ addUnique(table: string, columns: string[] | string, options?: CommonConstraintOptions): void;
7543
+ /**
7544
+ * @description Drops a foreign key from a table, uses a standard constraint name pattern: fk_${table}_${leftColumn}_${rightColumn}
7545
+ * @description If a custom constraint name was used to generate the foreign key, use `dropConstraint` instead
7546
+ */
7547
+ dropForeignKey(table: string, leftColumn: string, rightColumn: string): void;
7548
+ /**
7549
+ * @description Drops a UNIQUE constraint from a table
7550
+ * @description If no constraintName is provided, it computes the default name using columns
7551
+ */
7552
+ dropUnique(table: string, columnsOrConstraintName: string | string[], options?: CommonConstraintOptions): void;
7553
+ /**
7554
+ * @description Drops a primary key from a table
7555
+ */
7556
+ dropPrimaryKey(table: string): void;
7557
+ /**
7558
+ * @description Adds a foreign key to a table
7559
+ */
7560
+ addConstraint(table: string, ...options: ConstructorParameters<typeof ConstraintNode>): void;
7561
+ /**
7562
+ * @description Drops a constraint from a table
7563
+ */
7564
+ dropConstraint(table: string, constraintName: string): void;
7565
+ /**
7566
+ * @description Create database extension, only supported for postgres
7567
+ * @postgres Supports extensions like PostGIS, uuid-ossp, hstore, etc.
7568
+ * @mysql Extensions are not supported - outputs a comment
7569
+ * @sqlite Extensions are loaded dynamically - outputs a comment
7570
+ * @mssql Extensions are not supported - outputs a comment
7571
+ * @oracledb Extensions are not supported - outputs a comment
7572
+ */
7573
+ createExtension(extensionName: CommonPostgresExtensions, ifNotExists?: boolean): void;
7574
+ createExtension(extensionName: string, ifNotExists?: boolean): void;
7575
+ private generateAstInstance;
7576
+ }
7577
+
7197
7578
  declare abstract class Migration {
7198
7579
  dbType: SqlDataSourceType;
7199
7580
  migrationName: string;
@@ -7303,4 +7684,4 @@ declare const generateOpenApiModelWithMetadata: <T extends new () => Model>(mode
7303
7684
  $id?: string;
7304
7685
  }>;
7305
7686
 
7306
- export { type AbstractConstructor, type AdminJsActionOptions, type AdminJsAssets, type AdminJsBranding, type AdminJsInstance, type AdminJsLocale, type AdminJsOptions, type AdminJsPage, type AdminJsPropertyOptions, type AdminJsResourceOptions, type AdminJsSettings, type AnyConstructor, type AsymmetricEncryptionOptions, type BaseModelMethodOptions, type BaseModelRelationType, BaseSeeder, type BigIntFields, BigIntMixin, type BuildSelectType, type BuildSingleSelectType, type CacheAdapter, type CacheKeys, ClientMigrator, Collection, type ColumnDataTypeOption, type ColumnDataTypeOptionSimple, type ColumnDataTypeOptionWithBinary, type ColumnDataTypeOptionWithDatePrecision, type ColumnDataTypeOptionWithEnum, type ColumnDataTypeOptionWithLength, type ColumnDataTypeOptionWithPrecision, type ColumnDataTypeOptionWithScaleAndPrecision, type ColumnDataTypeOptionWithText, type ColumnOptions, type ColumnType, type CommonDataSourceInput, type ComposeBuildSelect, type ComposeSelect, type ConnectionPolicies, type Constructor, type DataSourceInput, type DataSourceType, type DateColumnOptions, DryModelQueryBuilder, DryQueryBuilder, type ExtractColumnName, type FetchHooks, type GetColumnType, type GetConnectionReturnType, HysteriaError, InMemoryAdapter, type IncrementFields, IncrementMixin, type IndexType, type LazyRelationType, type ManyOptions, type ManyToManyOptions, type ManyToManyStringOptions, Migration, type MigrationConfig, type MigrationConfigBase, type MixinColumns, MixinFactory, Model, type ModelInstanceType, ModelQueryBuilder, type ModelWithoutRelations, MongoDataSource, type MongoDataSourceInput$1 as MongoDataSourceInput, type MssqlConnectionInstance, type MssqlDataSourceInput, type MssqlPoolInstance, type MysqlConnectionInstance, type MysqlSqlDataSourceInput, type NotNullableMysqlSqlDataSourceInput, type NotNullableOracleDBDataSourceInput, type NotNullableOracleMssqlDataSourceInput, type NotNullablePostgresSqlDataSourceInput, type NotNullableSqliteDataSourceInput, type NumberModelKey, type OneOptions, type OracleDBDataSourceInput, type OracleDBPoolInstance, type PgPoolClientInstance, type PostgresSqlDataSourceInput, QueryBuilder, type RawModelOptions, RawNode, type RawQueryOptions, RedisCacheAdapter, type RedisFetchable, type RedisStorable, type RelatedInstance, type RelationQueryBuilderType, type ReplicationType, type SeederConfig, type SelectBrand, type SelectableColumn, type SelectedModel, type SlaveAlgorithm, type SlaveContext, type SqlCloneOptions, SqlDataSource, type SqlDataSourceInput, type SqlDataSourceModel, type SqlDataSourceType, type SqlDriverSpecificOptions, type SqlPoolType, type Sqlite3ConnectionOptions, type SqliteConnectionInstance, type SqliteDataSourceInput, type StartTransactionOptions, type SymmetricEncryptionOptions, type TableFormat, type ThroughModel, type TimestampFields, TimestampMixin, Transaction, type TransactionExecutionOptions, type UlidFields, UlidMixin, type UniqueType, type UseCacheReturnType, type UseConnectionInput, type UuidFields, UuidMixin, belongsTo, bigIntMixin, column, createMixin, createModelFactory, defineMigrator, generateOpenApiModel, generateOpenApiModelSchema, generateOpenApiModelWithMetadata, getCollectionProperties, getIndexes, getModelColumns, type getPoolReturnType, getPrimaryKey, getRelations, getRelationsMetadata, getUniques, hasMany, hasOne, incrementMixin, index, HysteriaLogger as logger, manyToMany, property, RedisDataSource as redis, timestampMixin, ulidMixin, unique, uuidMixin, view, withPerformance };
7687
+ export { type AbstractConstructor, type AdminJsActionOptions, type AdminJsAssets, type AdminJsBranding, type AdminJsInstance, type AdminJsLocale, type AdminJsOptions, type AdminJsPage, type AdminJsPropertyOptions, type AdminJsResourceOptions, type AdminJsSettings, type AnyConstructor, type AsymmetricEncryptionOptions, type BaseModelMethodOptions, type BaseModelRelationType, BaseSeeder, type BigIntFields, BigIntMixin, type BuildSelectType, type BuildSingleSelectType, type CacheAdapter, type CacheKeys, ClientMigrator, Collection, type ColumnDataTypeOption, type ColumnDataTypeOptionSimple, type ColumnDataTypeOptionWithBinary, type ColumnDataTypeOptionWithDatePrecision, type ColumnDataTypeOptionWithEnum, type ColumnDataTypeOptionWithLength, type ColumnDataTypeOptionWithPrecision, type ColumnDataTypeOptionWithScaleAndPrecision, type ColumnDataTypeOptionWithText, type ColumnOptions, type ColumnType, type CommonDataSourceInput, type ComposeBuildSelect, type ComposeSelect, type ConnectionPolicies, type Constructor, type DataSourceInput, type DataSourceType, type DateColumnOptions, DryModelQueryBuilder, DryQueryBuilder, type ExcludeMethods, type ExtractColumnName, type ExtractSourceColumn, type FetchHooks, type GetColumnType, type GetConnectionReturnType, HysteriaError, InMemoryAdapter, type IncrementFields, IncrementMixin, type IndexType, type LazyRelationType, type ManyOptions, type ManyToManyOptions, type ManyToManyStringOptions, Migration, type MigrationConfig, type MigrationConfigBase, type MixinColumns, MixinFactory, Model, type ModelDataProperties, type ModelInstanceMethods, type ModelInstanceType, ModelQueryBuilder, type ModelQueryResult, type ModelSelectTuple, type ModelSelectableInput, type ModelWithoutRelations, MongoDataSource, type MongoDataSourceInput$1 as MongoDataSourceInput, type MssqlConnectionInstance, type MssqlDataSourceInput, type MssqlPoolInstance, type MysqlConnectionInstance, type MysqlSqlDataSourceInput, type NotNullableMysqlSqlDataSourceInput, type NotNullableOracleDBDataSourceInput, type NotNullableOracleMssqlDataSourceInput, type NotNullablePostgresSqlDataSourceInput, type NotNullableSqliteDataSourceInput, type NumberModelKey, type OneOptions, type OracleDBDataSourceInput, type OracleDBPoolInstance, type PgPoolClientInstance, type PostgresSqlDataSourceInput, QueryBuilder, type RawModelOptions, RawNode, type RawQueryOptions, RedisCacheAdapter, type RedisFetchable, type RedisStorable, type RelatedInstance, type RelationQueryBuilderType, type ReplicationType, Schema, SchemaBuilder, type SeederConfig, type SelectBrand, type SelectableColumn, type SelectedModel, type SlaveAlgorithm, type SlaveContext, type SqlCloneOptions, SqlDataSource, type SqlDataSourceInput, type SqlDataSourceModel, type SqlDataSourceType, type SqlDriverSpecificOptions, type SqlPoolType, type Sqlite3ConnectionOptions, type SqliteConnectionInstance, type SqliteDataSourceInput, type StartTransactionOptions, type SymmetricEncryptionOptions, type TableFormat, type ThroughModel, type TimestampFields, TimestampMixin, Transaction, type TransactionExecutionOptions, type UlidFields, UlidMixin, type UniqueType, type UseCacheReturnType, type UseConnectionInput, type UuidFields, UuidMixin, belongsTo, bigIntMixin, column, createMixin, createModelFactory, defineMigrator, generateOpenApiModel, generateOpenApiModelSchema, generateOpenApiModelWithMetadata, getCollectionProperties, getIndexes, getModelColumns, type getPoolReturnType, getPrimaryKey, getRelations, getRelationsMetadata, getUniques, hasMany, hasOne, incrementMixin, index, HysteriaLogger as logger, manyToMany, property, RedisDataSource as redis, timestampMixin, ulidMixin, unique, uuidMixin, view, withPerformance };