durcno 1.0.0-alpha.15 → 1.0.0-alpha.17

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.
Files changed (56) hide show
  1. package/dist/bin.cjs +4 -2
  2. package/dist/src/columns/common.d.mts +1 -1
  3. package/dist/src/constraints/check.d.mts +1 -1
  4. package/dist/src/constraints/foreign-key.d.mts +61 -0
  5. package/dist/src/constraints/foreign-key.mjs +74 -0
  6. package/dist/src/cte.d.mts +16 -0
  7. package/dist/src/cte.mjs +5 -0
  8. package/dist/src/db.d.mts +24 -1
  9. package/dist/src/db.mjs +10 -1
  10. package/dist/src/filters/array.d.mts +1 -1
  11. package/dist/src/filters/index.d.mts +1 -1
  12. package/dist/src/filters/index.mjs +1 -1
  13. package/dist/src/filters/string.d.mts +1 -1
  14. package/dist/src/functions/aggregate.d.mts +24 -8
  15. package/dist/src/functions/aggregate.mjs +68 -9
  16. package/dist/src/functions/arithmetic.d.mts +67 -0
  17. package/dist/src/functions/arithmetic.mjs +123 -0
  18. package/dist/src/functions/index.d.mts +15 -18
  19. package/dist/src/functions/index.mjs +19 -23
  20. package/dist/src/functions/numeric.d.mts +16 -1
  21. package/dist/src/functions/numeric.mjs +45 -0
  22. package/dist/src/functions/pgvector.d.mts +4 -1
  23. package/dist/src/functions/pgvector.mjs +9 -0
  24. package/dist/src/functions/postgis.d.mts +3 -0
  25. package/dist/src/functions/postgis.mjs +9 -0
  26. package/dist/src/functions/string.d.mts +22 -1
  27. package/dist/src/functions/string.mjs +63 -0
  28. package/dist/src/index.d.mts +8 -5
  29. package/dist/src/index.mjs +3 -1
  30. package/dist/src/migration/snapshot.mjs +13 -0
  31. package/dist/src/query-builders/aggregates.d.mts +1 -1
  32. package/dist/src/query-builders/count.d.mts +1 -1
  33. package/dist/src/query-builders/delete.d.mts +14 -7
  34. package/dist/src/query-builders/delete.mjs +26 -9
  35. package/dist/src/query-builders/distinct.d.mts +1 -1
  36. package/dist/src/query-builders/exists.d.mts +1 -1
  37. package/dist/src/query-builders/first.d.mts +1 -1
  38. package/dist/src/query-builders/helpers.mjs +28 -0
  39. package/dist/src/query-builders/insert.d.mts +9 -5
  40. package/dist/src/query-builders/insert.mjs +19 -7
  41. package/dist/src/query-builders/orderby-clause.d.mts +1 -1
  42. package/dist/src/query-builders/pre.d.mts +1 -1
  43. package/dist/src/query-builders/query-promise.d.mts +2 -2
  44. package/dist/src/query-builders/query.d.mts +2 -1
  45. package/dist/src/query-builders/rq.d.mts +2 -2
  46. package/dist/src/query-builders/select.d.mts +14 -6
  47. package/dist/src/query-builders/select.mjs +37 -13
  48. package/dist/src/query-builders/update.d.mts +15 -8
  49. package/dist/src/query-builders/update.mjs +22 -9
  50. package/dist/src/query-builders/with.d.mts +51 -0
  51. package/dist/src/query-builders/with.mjs +47 -0
  52. package/dist/src/table.d.mts +5 -1
  53. package/dist/src/table.mjs +2 -2
  54. package/dist/src/virtual-table.d.mts +51 -0
  55. package/dist/src/virtual-table.mjs +55 -0
  56. package/package.json +1 -1
package/dist/bin.cjs CHANGED
@@ -9631,7 +9631,9 @@ function orderTables(tables, order) {
9631
9631
  Object.entries(tables).map(([tableName, table]) => {
9632
9632
  const references = Object.values(table.columns).map(
9633
9633
  (column) => column.references ? `${column.references.schema}.${column.references.table}` : void 0
9634
- ).filter((table2) => table2 !== void 0);
9634
+ ).filter(
9635
+ (table2) => table2 !== void 0 && table2 !== tableName
9636
+ );
9635
9637
  return [tableName, references];
9636
9638
  })
9637
9639
  );
@@ -10455,7 +10457,7 @@ async function status(options) {
10455
10457
  }
10456
10458
 
10457
10459
  // src/cli/index.ts
10458
- program.version("1.0.0-alpha.14");
10460
+ program.version("1.0.0-alpha.16");
10459
10461
  var Options = {
10460
10462
  config: ["--config <path>", "Path to the config file"]
10461
10463
  };
@@ -1,7 +1,7 @@
1
+ import { AnyFilter } from "../filters/index.mjs";
1
2
  import { CheckExpression } from "../constraints/check.mjs";
2
3
  import { entityType } from "../symbols.mjs";
3
4
  import { AnyColumn, StdTable, StdTableColumn } from "../table.mjs";
4
- import { AnyFilter } from "../filters/index.mjs";
5
5
  import { Arg } from "../query-builders/pre.mjs";
6
6
  import { Query, QueryContext } from "../query-builders/query.mjs";
7
7
  import { Sql } from "../sql.mjs";
@@ -1,5 +1,5 @@
1
- import { AnyColumn, TableAnyColumn } from "../table.mjs";
2
1
  import { AnyFilter, Filter } from "../filters/index.mjs";
2
+ import { AnyColumn, TableAnyColumn } from "../table.mjs";
3
3
  import { QueryContext } from "../query-builders/query.mjs";
4
4
  import { Sql } from "../sql.mjs";
5
5
 
@@ -0,0 +1,61 @@
1
+ import { Column, OnDeleteAction } from "../columns/common.mjs";
2
+ import { AnyColumn, StdTableColumn } from "../table.mjs";
3
+
4
+ //#region src/constraints/foreign-key.d.ts
5
+ /**
6
+ * Intermediate builder returned by `fk(column)`.
7
+ * Call `.references(refColumn)` to finalise into a `ForeignKey`.
8
+ */
9
+ declare class ForeignKeyBuilder<TCol extends AnyColumn> {
10
+ #private;
11
+ constructor(column: StdTableColumn<TCol>);
12
+ /**
13
+ * Specify the referenced column.
14
+ * The referenced column's value type must match the source column's value type.
15
+ */
16
+ references<TRefCol extends Column<any, TCol["ValType"]>>(ref: StdTableColumn<TRefCol>): ForeignKey;
17
+ }
18
+ /**
19
+ * Represents a finalised table-level foreign key constraint.
20
+ * Created via `fk(column).references(refColumn)`.
21
+ */
22
+ declare class ForeignKey {
23
+ #private;
24
+ constructor(column: StdTableColumn, reference: StdTableColumn, onDelete: OnDeleteAction);
25
+ /**
26
+ * Override the default `CASCADE` delete action.
27
+ *
28
+ * @param action - The `ON DELETE` action to apply.
29
+ * @returns `this` for chaining.
30
+ */
31
+ onDelete(action: OnDeleteAction): this;
32
+ _: {
33
+ /** Returns the source column of the foreign key. */getColumn: () => StdTableColumn; /** Returns the referenced column of the foreign key. */
34
+ getReference: () => StdTableColumn; /** Returns the configured `ON DELETE` action. */
35
+ getOnDelete: () => OnDeleteAction;
36
+ };
37
+ }
38
+ /**
39
+ * Entry point for defining a table-level foreign key constraint.
40
+ * Use inside the `foreignKeys` callback in `TableExtra`.
41
+ *
42
+ * Because `foreignKeys` receives the fully-constructed table as a typed
43
+ * parameter `t`, column references are already resolved — no thunk needed.
44
+ *
45
+ * @param column - The source column on this table.
46
+ * @returns A `ForeignKeyBuilder` to chain `.references(refColumn)` on.
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * table("public", "comments", { ... }, {
51
+ * foreignKeys: (t, fk) => [
52
+ * fk(t.parentId).references(t.id).onDelete("SET NULL"),
53
+ * ],
54
+ * });
55
+ * ```
56
+ */
57
+ declare function fk<TCol extends AnyColumn>(column: StdTableColumn<TCol>): ForeignKeyBuilder<TCol>;
58
+ /** The type of the `fk` helper injected into the `foreignKeys` callback. */
59
+ type ForeignKeyFn = typeof fk;
60
+ //#endregion
61
+ export { ForeignKey, ForeignKeyFn };
@@ -0,0 +1,74 @@
1
+ //#region src/constraints/foreign-key.ts
2
+ /**
3
+ * Intermediate builder returned by `fk(column)`.
4
+ * Call `.references(refColumn)` to finalise into a `ForeignKey`.
5
+ */
6
+ var ForeignKeyBuilder = class {
7
+ #column;
8
+ constructor(column) {
9
+ this.#column = column;
10
+ }
11
+ /**
12
+ * Specify the referenced column.
13
+ * The referenced column's value type must match the source column's value type.
14
+ */
15
+ references(ref) {
16
+ return new ForeignKey(this.#column, ref, "CASCADE");
17
+ }
18
+ };
19
+ /**
20
+ * Represents a finalised table-level foreign key constraint.
21
+ * Created via `fk(column).references(refColumn)`.
22
+ */
23
+ var ForeignKey = class {
24
+ #column;
25
+ #reference;
26
+ #onDelete;
27
+ constructor(column, reference, onDelete) {
28
+ this.#column = column;
29
+ this.#reference = reference;
30
+ this.#onDelete = onDelete;
31
+ }
32
+ /**
33
+ * Override the default `CASCADE` delete action.
34
+ *
35
+ * @param action - The `ON DELETE` action to apply.
36
+ * @returns `this` for chaining.
37
+ */
38
+ onDelete(action) {
39
+ this.#onDelete = action;
40
+ return this;
41
+ }
42
+ _ = {
43
+ /** Returns the source column of the foreign key. */
44
+ getColumn: () => this.#column,
45
+ /** Returns the referenced column of the foreign key. */
46
+ getReference: () => this.#reference,
47
+ /** Returns the configured `ON DELETE` action. */
48
+ getOnDelete: () => this.#onDelete
49
+ };
50
+ };
51
+ /**
52
+ * Entry point for defining a table-level foreign key constraint.
53
+ * Use inside the `foreignKeys` callback in `TableExtra`.
54
+ *
55
+ * Because `foreignKeys` receives the fully-constructed table as a typed
56
+ * parameter `t`, column references are already resolved — no thunk needed.
57
+ *
58
+ * @param column - The source column on this table.
59
+ * @returns A `ForeignKeyBuilder` to chain `.references(refColumn)` on.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * table("public", "comments", { ... }, {
64
+ * foreignKeys: (t, fk) => [
65
+ * fk(t.parentId).references(t.id).onDelete("SET NULL"),
66
+ * ],
67
+ * });
68
+ * ```
69
+ */
70
+ function fk(column) {
71
+ return new ForeignKeyBuilder(column);
72
+ }
73
+ //#endregion
74
+ export { fk };
@@ -0,0 +1,16 @@
1
+ import { VirtualTable } from "./virtual-table.mjs";
2
+ import { AnyColumn } from "./table.mjs";
3
+
4
+ //#region src/cte.d.ts
5
+ declare class Cte<TName extends string, TColumns extends Record<string, AnyColumn>> extends VirtualTable<TName, TColumns> {
6
+ /** Phantom type — extracts `TName` safely through `CteWithColumns` intersections. */
7
+ readonly $cteName: TName;
8
+ }
9
+ type CteWithColumns<TName extends string, TColumns extends Record<string, AnyColumn>> = Cte<TName, TColumns> & TColumns;
10
+ type AnyCteWithColumns = CteWithColumns<any, Record<any, any>>;
11
+ /** Maps a tuple of `CteWithColumns` to an object keyed by CTE name. */
12
+ type CtesByName<TCtes extends AnyCteWithColumns[]> = { [K in TCtes[number] as K extends {
13
+ $cteName: infer TName extends string;
14
+ } ? TName : never]: K };
15
+ //#endregion
16
+ export { AnyCteWithColumns, Cte, CteWithColumns, CtesByName };
@@ -0,0 +1,5 @@
1
+ import { VirtualTable } from "./virtual-table.mjs";
2
+ //#region src/cte.ts
3
+ var Cte = class extends VirtualTable {};
4
+ //#endregion
5
+ export { Cte };
package/dist/src/db.d.mts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { CamelToSnake, Valueof } from "./types.mjs";
2
- import { AnyColumn, AnyRelations, IsTableWC, Relations, TableWCorNever, TableWithColumns } from "./table.mjs";
2
+ import { AnySubquery, InferQueryColumns } from "./virtual-table.mjs";
3
3
  import { SelectBuilder } from "./query-builders/select.mjs";
4
4
  import { FilterExpression } from "./filters/index.mjs";
5
+ import { AnyColumn, AnyRelations, IsTableWC, Relations, TableWCorNever, TableWithColumns } from "./table.mjs";
6
+ import { AnyCteWithColumns, CteWithColumns } from "./cte.mjs";
5
7
  import { Config } from "./index.mjs";
6
8
  import { AggregateQuery } from "./query-builders/aggregates.mjs";
7
9
  import { CountQuery } from "./query-builders/count.mjs";
@@ -13,6 +15,7 @@ import { InsertBuilder } from "./query-builders/insert.mjs";
13
15
  import { RawQuery } from "./query-builders/raw.mjs";
14
16
  import { RelationQueryBuilder } from "./query-builders/rq.mjs";
15
17
  import { UpdateBuilder } from "./query-builders/update.mjs";
18
+ import { WithStatement } from "./query-builders/with.mjs";
16
19
  import { $Pool, QueryExecutor } from "./connectors/common.mjs";
17
20
 
18
21
  //#region src/db.d.ts
@@ -149,6 +152,26 @@ declare class Base<TTName extends string, TTables extends Record<TTName, TableWi
149
152
  * @returns A RawQuery instance that resolves to the query result (or transformed result if handler provided)
150
153
  */
151
154
  raw<TReturn = unknown>(query: string, args: (string | number | null)[] | undefined, rowsHandler: ((rows: any[]) => TReturn) | undefined): RawQuery<TReturn>;
155
+ /**
156
+ * Create a CTE definition by name.
157
+ * @param name The CTE name to be used in the WITH clause
158
+ * @returns An object with `.as()` to bind a subquery
159
+ *
160
+ * @example
161
+ * const activeCte = db.with("activeUsers").as(db.from(Users).select(...));
162
+ */
163
+ with<TCteName extends string>(name: TCteName): {
164
+ as: <TQuery extends AnySubquery>(query: TQuery) => CteWithColumns<TCteName, InferQueryColumns<TCteName, TQuery>>;
165
+ };
166
+ /**
167
+ * Attach one or more CTEs to a statement.
168
+ * @param ctes One or more CTE instances created via `db.with("name").as(...)`
169
+ * @returns A `WithStatement` to build the SELECT/INSERT/UPDATE/DELETE against
170
+ *
171
+ * @example
172
+ * const rows = await db.with(activeCte).from(ctes => ctes.activeUsers).select();
173
+ */
174
+ with<TCtes extends [AnyCteWithColumns, ...AnyCteWithColumns[]]>(...ctes: TCtes): WithStatement<TCtes, TPrepare>;
152
175
  }
153
176
  declare class DB<TTName extends string, TTables extends Record<TTName, TableWithColumns<string, string, Record<string, AnyColumn>>>, TAllRelations extends Record<StdTableFullName, AnyRelations>> extends Base<TTName, TTables, TAllRelations, false> {
154
177
  #private;
package/dist/src/db.mjs CHANGED
@@ -1,5 +1,8 @@
1
1
  import { Query } from "./query-builders/query.mjs";
2
2
  import { is } from "./entity.mjs";
3
+ import { Relations, Table } from "./table.mjs";
4
+ import { bindVirtualTableColumns } from "./virtual-table.mjs";
5
+ import { Cte } from "./cte.mjs";
3
6
  import { AggregateQuery } from "./query-builders/aggregates.mjs";
4
7
  import { CountQuery } from "./query-builders/count.mjs";
5
8
  import { DeleteQuery } from "./query-builders/delete.mjs";
@@ -11,7 +14,7 @@ import { RawQuery } from "./query-builders/raw.mjs";
11
14
  import { RelationQueryBuilder } from "./query-builders/rq.mjs";
12
15
  import { SelectBuilder } from "./query-builders/select.mjs";
13
16
  import { UpdateBuilder } from "./query-builders/update.mjs";
14
- import { Relations, Table } from "./table.mjs";
17
+ import { WithStatement } from "./query-builders/with.mjs";
15
18
  //#region src/db.ts
16
19
  var Base = class {
17
20
  #allRelations;
@@ -119,6 +122,12 @@ var Base = class {
119
122
  raw(query, args = [], rowsHandler) {
120
123
  return new RawQuery(query, args, rowsHandler, this.#getExecutor());
121
124
  }
125
+ with(nameOrFirstCte, ...restCtes) {
126
+ if (typeof nameOrFirstCte === "string") return { as: (query) => {
127
+ return bindVirtualTableColumns(new Cte(nameOrFirstCte, query.getResolvedColumns(), query));
128
+ } };
129
+ return new WithStatement([nameOrFirstCte, ...restCtes], this.#getExecutor(), this.$.pre);
130
+ }
122
131
  };
123
132
  var DB = class extends Base {
124
133
  #pool;
@@ -1,5 +1,5 @@
1
- import { AnyColumn } from "../table.mjs";
2
1
  import { Filter } from "./index.mjs";
2
+ import { AnyColumn } from "../table.mjs";
3
3
  import { Arg, IsArg } from "../query-builders/pre.mjs";
4
4
  import { Query, QueryContext } from "../query-builders/query.mjs";
5
5
 
@@ -1,7 +1,7 @@
1
1
  import { BasicTypes, Or } from "../types.mjs";
2
- import { AnyColumn } from "../table.mjs";
3
2
  import { AnyScalarSqlFn } from "../functions/index.mjs";
4
3
  import { SelectQuery } from "../query-builders/select.mjs";
4
+ import { AnyColumn } from "../table.mjs";
5
5
  import { Arg, IsArg } from "../query-builders/pre.mjs";
6
6
  import { Query, QueryContext } from "../query-builders/query.mjs";
7
7
  import { Sql } from "../sql.mjs";
@@ -119,7 +119,7 @@ var InCondition = class extends Filter {
119
119
  } else {
120
120
  this.field.toQuery(query, ctx);
121
121
  query.sql += " IN (";
122
- query.sql += this.values.toQuery();
122
+ this.values.toQuery(query);
123
123
  query.sql += ")";
124
124
  }
125
125
  }
@@ -1,5 +1,5 @@
1
- import { Column } from "../columns/common.mjs";
2
1
  import { Filter } from "./index.mjs";
2
+ import { Column } from "../columns/common.mjs";
3
3
  import { Arg, IsArg } from "../query-builders/pre.mjs";
4
4
  import { Query, QueryContext } from "../query-builders/query.mjs";
5
5
 
@@ -1,5 +1,5 @@
1
- import { AnyColumn } from "../table.mjs";
2
1
  import { AnyScalarSqlFn, ExprColumns, HasArg, SqlFn } from "./index.mjs";
2
+ import { AnyColumn } from "../table.mjs";
3
3
  import { Query, QueryContext } from "../query-builders/query.mjs";
4
4
 
5
5
  //#region src/functions/aggregate.d.ts
@@ -36,6 +36,9 @@ declare class CountFn<TExpr extends AnyColumn> extends SqlFn<TExpr, false, "aggr
36
36
  private readonly expr;
37
37
  readonly isAggregate = true;
38
38
  constructor(expr: TExpr);
39
+ toDriverValue(value: number | null): unknown;
40
+ toSQLValue(value: number | null): string;
41
+ fromDriverValue(value: unknown): number | null;
39
42
  /** Appends `count(expr)` to the query SQL. */
40
43
  toQuery(query: Query, ctx?: QueryContext): void;
41
44
  }
@@ -50,6 +53,9 @@ declare class CountFn<TExpr extends AnyColumn> extends SqlFn<TExpr, false, "aggr
50
53
  */
51
54
  declare class CountStarFn extends SqlFn<never, false, "aggregate", "numeric", number> {
52
55
  readonly isAggregate = true;
56
+ toDriverValue(value: number | null): unknown;
57
+ toSQLValue(value: number | null): string;
58
+ fromDriverValue(value: unknown): number | null;
53
59
  /** Appends `count(*)` to the query SQL. */
54
60
  toQuery(query: Query, _ctx?: QueryContext): void;
55
61
  }
@@ -66,6 +72,9 @@ declare class CountDistinctFn<TExpr extends AnyColumn> extends SqlFn<TExpr, fals
66
72
  private readonly expr;
67
73
  readonly isAggregate = true;
68
74
  constructor(expr: TExpr);
75
+ toDriverValue(value: number | null): unknown;
76
+ toSQLValue(value: number | null): string;
77
+ fromDriverValue(value: unknown): number | null;
69
78
  /** Appends `count(DISTINCT expr)` to the query SQL. */
70
79
  toQuery(query: Query, ctx?: QueryContext): void;
71
80
  }
@@ -111,6 +120,9 @@ declare class SumFn<TExpr extends NumericAggregateInput> extends SqlFn<ExprColum
111
120
  private readonly expr;
112
121
  readonly isAggregate = true;
113
122
  constructor(expr: TExpr);
123
+ toDriverValue(value: TExpr["$"]["TsType"] | null): unknown;
124
+ toSQLValue(value: TExpr["$"]["TsType"] | null): string;
125
+ fromDriverValue(value: unknown): TExpr["$"]["TsType"] | null;
114
126
  /** Appends `sum(expr)` to the query SQL. */
115
127
  toQuery(query: Query, ctx?: QueryContext): void;
116
128
  }
@@ -140,12 +152,12 @@ declare class AvgFn<TExpr extends NumericAggregateInput> extends SqlFn<ExprColum
140
152
  private readonly expr;
141
153
  readonly isAggregate = true;
142
154
  constructor(expr: TExpr);
155
+ toDriverValue(value: TExpr["$"]["TsType"] | null): unknown;
156
+ toSQLValue(value: TExpr["$"]["TsType"] | null): string;
143
157
  /**
144
158
  * Preserves the raw PostgreSQL `numeric` string (e.g. `"2.5000000000"`).
145
- * The default `SqlFn.fromDriver` would coerce numeric strings to `number`,
146
- * which contradicts the declared `string | null` return type.
147
159
  */
148
- fromDriver(value: unknown): string | null;
160
+ fromDriverValue(value: unknown): TExpr["$"]["TsType"] | null;
149
161
  /** Appends `avg(expr)` to the query SQL. */
150
162
  toQuery(query: Query, ctx?: QueryContext): void;
151
163
  }
@@ -176,11 +188,13 @@ declare class MinFn<TExpr extends AggregateInput> extends SqlFn<ExprColumns<TExp
176
188
  private readonly expr;
177
189
  readonly isAggregate = true;
178
190
  constructor(expr: TExpr);
191
+ toDriverValue(value: TExpr["$"]["TsType"] | null): unknown;
192
+ toSQLValue(value: TExpr["$"]["TsType"] | null): string;
179
193
  /**
180
- * Delegates to the inner expression's own `fromDriver` so that the result
194
+ * Delegates to the inner expression's own conversion so that the result
181
195
  * is deserialized to the same TypeScript type as the wrapped column/function.
182
196
  */
183
- fromDriver(value: unknown): TExpr["$"]["TsType"] | null;
197
+ fromDriverValue(value: unknown): TExpr["$"]["TsType"] | null;
184
198
  /** Appends `min(expr)` to the query SQL. */
185
199
  toQuery(query: Query, ctx?: QueryContext): void;
186
200
  }
@@ -211,11 +225,13 @@ declare class MaxFn<TExpr extends AggregateInput> extends SqlFn<ExprColumns<TExp
211
225
  private readonly expr;
212
226
  readonly isAggregate = true;
213
227
  constructor(expr: TExpr);
228
+ toDriverValue(value: TExpr["$"]["TsType"] | null): unknown;
229
+ toSQLValue(value: TExpr["$"]["TsType"] | null): string;
214
230
  /**
215
- * Delegates to the inner expression's own `fromDriver` so that the result
231
+ * Delegates to the inner expression's own conversion so that the result
216
232
  * is deserialized to the same TypeScript type as the wrapped column/function.
217
233
  */
218
- fromDriver(value: unknown): TExpr["$"]["TsType"] | null;
234
+ fromDriverValue(value: unknown): TExpr["$"]["TsType"] | null;
219
235
  /** Appends `max(expr)` to the query SQL. */
220
236
  toQuery(query: Query, ctx?: QueryContext): void;
221
237
  }
@@ -1,4 +1,5 @@
1
1
  import { SqlFn } from "./index.mjs";
2
+ import { isCol } from "../entity.mjs";
2
3
  //#region src/functions/aggregate.ts
3
4
  /**
4
5
  * SQL aggregate expression: `count(col)`
@@ -17,6 +18,15 @@ var CountFn = class extends SqlFn {
17
18
  super();
18
19
  this.expr = expr;
19
20
  }
21
+ toDriverValue(value) {
22
+ return value;
23
+ }
24
+ toSQLValue(value) {
25
+ return SqlFn._numericToSQL(value);
26
+ }
27
+ fromDriverValue(value) {
28
+ return SqlFn._numericFromDriver(value);
29
+ }
20
30
  /** Appends `count(expr)` to the query SQL. */
21
31
  toQuery(query, ctx) {
22
32
  query.sql += "count(";
@@ -35,6 +45,15 @@ var CountFn = class extends SqlFn {
35
45
  */
36
46
  var CountStarFn = class extends SqlFn {
37
47
  isAggregate = true;
48
+ toDriverValue(value) {
49
+ return value;
50
+ }
51
+ toSQLValue(value) {
52
+ return SqlFn._numericToSQL(value);
53
+ }
54
+ fromDriverValue(value) {
55
+ return SqlFn._numericFromDriver(value);
56
+ }
38
57
  /** Appends `count(*)` to the query SQL. */
39
58
  toQuery(query, _ctx) {
40
59
  query.sql += "count(*)";
@@ -55,6 +74,15 @@ var CountDistinctFn = class extends SqlFn {
55
74
  super();
56
75
  this.expr = expr;
57
76
  }
77
+ toDriverValue(value) {
78
+ return value;
79
+ }
80
+ toSQLValue(value) {
81
+ return SqlFn._numericToSQL(value);
82
+ }
83
+ fromDriverValue(value) {
84
+ return SqlFn._numericFromDriver(value);
85
+ }
58
86
  /** Appends `count(DISTINCT expr)` to the query SQL. */
59
87
  toQuery(query, ctx) {
60
88
  query.sql += "count(DISTINCT ";
@@ -96,6 +124,17 @@ var SumFn = class extends SqlFn {
96
124
  super();
97
125
  this.expr = expr;
98
126
  }
127
+ toDriverValue(value) {
128
+ return value;
129
+ }
130
+ toSQLValue(value) {
131
+ return SqlFn._numericToSQL(value);
132
+ }
133
+ fromDriverValue(value) {
134
+ if (value === null) return null;
135
+ if (typeof value === "bigint") return value;
136
+ return Number(value);
137
+ }
99
138
  /** Appends `sum(expr)` to the query SQL. */
100
139
  toQuery(query, ctx) {
101
140
  query.sql += "sum(";
@@ -133,12 +172,16 @@ var AvgFn = class extends SqlFn {
133
172
  super();
134
173
  this.expr = expr;
135
174
  }
175
+ toDriverValue(value) {
176
+ return value;
177
+ }
178
+ toSQLValue(value) {
179
+ return SqlFn._stringToSQL(value);
180
+ }
136
181
  /**
137
182
  * Preserves the raw PostgreSQL `numeric` string (e.g. `"2.5000000000"`).
138
- * The default `SqlFn.fromDriver` would coerce numeric strings to `number`,
139
- * which contradicts the declared `string | null` return type.
140
183
  */
141
- fromDriver(value) {
184
+ fromDriverValue(value) {
142
185
  if (value === null) return null;
143
186
  return value;
144
187
  }
@@ -180,13 +223,21 @@ var MinFn = class extends SqlFn {
180
223
  super();
181
224
  this.expr = expr;
182
225
  }
226
+ toDriverValue(value) {
227
+ return value;
228
+ }
229
+ toSQLValue(value) {
230
+ if (isCol(this.expr)) return this.expr.toSQLScalar(value);
231
+ return this.expr.toSQLValue(value);
232
+ }
183
233
  /**
184
- * Delegates to the inner expression's own `fromDriver` so that the result
234
+ * Delegates to the inner expression's own conversion so that the result
185
235
  * is deserialized to the same TypeScript type as the wrapped column/function.
186
236
  */
187
- fromDriver(value) {
237
+ fromDriverValue(value) {
188
238
  if (value === null) return null;
189
- return this.expr.fromDriver(value);
239
+ if (isCol(this.expr)) return this.expr.fromDriverScalar(value);
240
+ return this.expr.fromDriverValue(value);
190
241
  }
191
242
  /** Appends `min(expr)` to the query SQL. */
192
243
  toQuery(query, ctx) {
@@ -226,13 +277,21 @@ var MaxFn = class extends SqlFn {
226
277
  super();
227
278
  this.expr = expr;
228
279
  }
280
+ toDriverValue(value) {
281
+ return value;
282
+ }
283
+ toSQLValue(value) {
284
+ if (isCol(this.expr)) return this.expr.toSQLScalar(value);
285
+ return this.expr.toSQLValue(value);
286
+ }
229
287
  /**
230
- * Delegates to the inner expression's own `fromDriver` so that the result
288
+ * Delegates to the inner expression's own conversion so that the result
231
289
  * is deserialized to the same TypeScript type as the wrapped column/function.
232
290
  */
233
- fromDriver(value) {
291
+ fromDriverValue(value) {
234
292
  if (value === null) return null;
235
- return this.expr.fromDriver(value);
293
+ if (isCol(this.expr)) return this.expr.fromDriverScalar(value);
294
+ return this.expr.fromDriverValue(value);
236
295
  }
237
296
  /** Appends `max(expr)` to the query SQL. */
238
297
  toQuery(query, ctx) {
@@ -0,0 +1,67 @@
1
+ import { Or } from "../types.mjs";
2
+ import { AnySqlFn, ExprColumns, HasArg, SqlFn } from "./index.mjs";
3
+ import { AnyScalarColumn } from "../table.mjs";
4
+ import { Arg, IsArg } from "../query-builders/pre.mjs";
5
+ import { Query, QueryContext } from "../query-builders/query.mjs";
6
+
7
+ //#region src/functions/arithmetic.d.ts
8
+ /**
9
+ * Union of every valid operand for arithmetic operators:
10
+ * a numeric column or SqlFn, a plain number literal, or an `Arg<number>`.
11
+ */
12
+ type NumericOperand = ((AnyScalarColumn | AnySqlFn) & {
13
+ $: {
14
+ PgType: "numeric";
15
+ };
16
+ }) | number | Arg<number>;
17
+ /**
18
+ * Computes the `THasArg` slot for a two-operand arithmetic expression.
19
+ * Resolves to `true` if either operand embeds an `Arg` or is itself an `Arg`.
20
+ */
21
+ type BinaryOpHasArg<TLeft extends NumericOperand, TRight extends NumericOperand> = Or<Or<HasArg<TLeft>, IsArg<TLeft>>, Or<HasArg<TRight>, IsArg<TRight>>>;
22
+ declare class AddFn<TLeft extends NumericOperand, TRight extends NumericOperand> extends SqlFn<ExprColumns<TLeft> | ExprColumns<TRight>, BinaryOpHasArg<TLeft, TRight>, "scalar", "numeric", number> {
23
+ private readonly left;
24
+ private readonly right;
25
+ constructor(left: TLeft, right: TRight);
26
+ toDriverValue(value: number | null): unknown;
27
+ toSQLValue(value: number | null): string;
28
+ fromDriverValue(value: unknown): number | null;
29
+ toQuery(query: Query, ctx?: QueryContext): void;
30
+ }
31
+ /** Returns the sum of two numeric expressions. */
32
+ declare function add<TLeft extends NumericOperand, TRight extends NumericOperand>(left: TLeft, right: TRight): AddFn<TLeft, TRight>;
33
+ declare class SubFn<TLeft extends NumericOperand, TRight extends NumericOperand> extends SqlFn<ExprColumns<TLeft> | ExprColumns<TRight>, BinaryOpHasArg<TLeft, TRight>, "scalar", "numeric", number> {
34
+ private readonly left;
35
+ private readonly right;
36
+ constructor(left: TLeft, right: TRight);
37
+ toDriverValue(value: number | null): unknown;
38
+ toSQLValue(value: number | null): string;
39
+ fromDriverValue(value: unknown): number | null;
40
+ toQuery(query: Query, ctx?: QueryContext): void;
41
+ }
42
+ /** Returns the difference of two numeric expressions. */
43
+ declare function sub<TLeft extends NumericOperand, TRight extends NumericOperand>(left: TLeft, right: TRight): SubFn<TLeft, TRight>;
44
+ declare class MulFn<TLeft extends NumericOperand, TRight extends NumericOperand> extends SqlFn<ExprColumns<TLeft> | ExprColumns<TRight>, BinaryOpHasArg<TLeft, TRight>, "scalar", "numeric", number> {
45
+ private readonly left;
46
+ private readonly right;
47
+ constructor(left: TLeft, right: TRight);
48
+ toDriverValue(value: number | null): unknown;
49
+ toSQLValue(value: number | null): string;
50
+ fromDriverValue(value: unknown): number | null;
51
+ toQuery(query: Query, ctx?: QueryContext): void;
52
+ }
53
+ /** Returns the product of two numeric expressions. */
54
+ declare function mul<TLeft extends NumericOperand, TRight extends NumericOperand>(left: TLeft, right: TRight): MulFn<TLeft, TRight>;
55
+ declare class DivFn<TLeft extends NumericOperand, TRight extends NumericOperand> extends SqlFn<ExprColumns<TLeft> | ExprColumns<TRight>, BinaryOpHasArg<TLeft, TRight>, "scalar", "numeric", number> {
56
+ private readonly left;
57
+ private readonly right;
58
+ constructor(left: TLeft, right: TRight);
59
+ toDriverValue(value: number | null): unknown;
60
+ toSQLValue(value: number | null): string;
61
+ fromDriverValue(value: unknown): number | null;
62
+ toQuery(query: Query, ctx?: QueryContext): void;
63
+ }
64
+ /** Returns the quotient of two numeric expressions. */
65
+ declare function div<TLeft extends NumericOperand, TRight extends NumericOperand>(left: TLeft, right: TRight): DivFn<TLeft, TRight>;
66
+ //#endregion
67
+ export { add, div, mul, sub };