@prisma-next/sql-relational-core 0.3.0-pr.99.1 → 0.3.0-pr.99.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.
Files changed (41) hide show
  1. package/dist/ast/predicate.d.ts +2 -2
  2. package/dist/ast/predicate.d.ts.map +1 -1
  3. package/dist/ast/types.d.ts +21 -9
  4. package/dist/ast/types.d.ts.map +1 -1
  5. package/dist/{chunk-D4JLPIWO.js → chunk-2BWK6XEY.js} +1 -1
  6. package/dist/chunk-2BWK6XEY.js.map +1 -0
  7. package/dist/{chunk-5N34PNVZ.js → chunk-2MAKNVCP.js} +25 -1
  8. package/dist/chunk-2MAKNVCP.js.map +1 -0
  9. package/dist/{chunk-M23L3JHG.js → chunk-3F4RFQIB.js} +45 -35
  10. package/dist/chunk-3F4RFQIB.js.map +1 -0
  11. package/dist/{chunk-J6O2HVBM.js → chunk-HV334QHG.js} +2 -2
  12. package/dist/{chunk-J6O2HVBM.js.map → chunk-HV334QHG.js.map} +1 -1
  13. package/dist/{chunk-ILJ6T6YP.js → chunk-YXD25S5I.js} +29 -11
  14. package/dist/chunk-YXD25S5I.js.map +1 -0
  15. package/dist/exports/ast.js +2 -2
  16. package/dist/exports/guards.d.ts +1 -1
  17. package/dist/exports/guards.d.ts.map +1 -1
  18. package/dist/exports/guards.js +13 -3
  19. package/dist/exports/operations-registry.js +2 -2
  20. package/dist/exports/schema.js +3 -4
  21. package/dist/exports/types.js +1 -1
  22. package/dist/index.js +5 -5
  23. package/dist/operations-registry.d.ts.map +1 -1
  24. package/dist/schema.d.ts +14 -9
  25. package/dist/schema.d.ts.map +1 -1
  26. package/dist/types.d.ts +69 -30
  27. package/dist/types.d.ts.map +1 -1
  28. package/dist/utils/guards.d.ts +43 -16
  29. package/dist/utils/guards.d.ts.map +1 -1
  30. package/package.json +7 -7
  31. package/src/ast/predicate.ts +3 -11
  32. package/src/ast/types.ts +23 -9
  33. package/src/exports/guards.ts +5 -0
  34. package/src/operations-registry.ts +112 -73
  35. package/src/schema.ts +40 -29
  36. package/src/types.ts +102 -52
  37. package/src/utils/guards.ts +88 -18
  38. package/dist/chunk-5N34PNVZ.js.map +0 -1
  39. package/dist/chunk-D4JLPIWO.js.map +0 -1
  40. package/dist/chunk-ILJ6T6YP.js.map +0 -1
  41. package/dist/chunk-M23L3JHG.js.map +0 -1
@@ -1,17 +1,9 @@
1
- import type {
2
- BinaryExpr,
3
- BinaryOp,
4
- ColumnRef,
5
- ExistsExpr,
6
- OperationExpr,
7
- ParamRef,
8
- SelectAst,
9
- } from './types';
1
+ import type { BinaryExpr, BinaryOp, ExistsExpr, Expression, ParamRef, SelectAst } from './types';
10
2
 
11
3
  export function createBinaryExpr(
12
4
  op: BinaryOp,
13
- left: ColumnRef | OperationExpr,
14
- right: ColumnRef | ParamRef,
5
+ left: Expression,
6
+ right: Expression | ParamRef,
15
7
  ): BinaryExpr {
16
8
  return {
17
9
  kind: 'bin',
package/src/ast/types.ts CHANGED
@@ -32,13 +32,27 @@ export interface OperationExpr {
32
32
  readonly kind: 'operation';
33
33
  readonly method: string;
34
34
  readonly forTypeId: string;
35
- readonly self: ColumnRef | OperationExpr;
36
- readonly args: ReadonlyArray<ColumnRef | ParamRef | LiteralExpr | OperationExpr>;
35
+ readonly self: Expression;
36
+ readonly args: ReadonlyArray<Expression | ParamRef | LiteralExpr>;
37
37
  readonly returns: ReturnSpec;
38
38
  readonly lowering: SqlLoweringSpec;
39
39
  }
40
40
 
41
- export function isOperationExpr(expr: ColumnRef | OperationExpr): expr is OperationExpr {
41
+ /**
42
+ * Unified expression type - the canonical AST representation for column references
43
+ * and operation expressions. This is what all builders convert to via toExpr().
44
+ */
45
+ export type Expression = ColumnRef | OperationExpr;
46
+
47
+ /**
48
+ * Interface for any builder that can produce an Expression.
49
+ * Implemented by ColumnBuilder and ExpressionBuilder.
50
+ */
51
+ export interface ExpressionSource {
52
+ toExpr(): Expression;
53
+ }
54
+
55
+ export function isOperationExpr(expr: Expression): expr is OperationExpr {
42
56
  return expr.kind === 'operation';
43
57
  }
44
58
 
@@ -47,8 +61,8 @@ export type BinaryOp = 'eq' | 'neq' | 'gt' | 'lt' | 'gte' | 'lte';
47
61
  export interface BinaryExpr {
48
62
  readonly kind: 'bin';
49
63
  readonly op: BinaryOp;
50
- readonly left: ColumnRef | OperationExpr;
51
- readonly right: ColumnRef | ParamRef;
64
+ readonly left: Expression;
65
+ readonly right: Expression | ParamRef;
52
66
  }
53
67
 
54
68
  export interface ExistsExpr {
@@ -82,9 +96,9 @@ export interface IncludeAst {
82
96
  readonly table: TableRef;
83
97
  readonly on: JoinOnExpr;
84
98
  readonly where?: BinaryExpr | ExistsExpr;
85
- readonly orderBy?: ReadonlyArray<{ expr: ColumnRef | OperationExpr; dir: Direction }>;
99
+ readonly orderBy?: ReadonlyArray<{ expr: Expression; dir: Direction }>;
86
100
  readonly limit?: number;
87
- readonly project: ReadonlyArray<{ alias: string; expr: ColumnRef | OperationExpr }>;
101
+ readonly project: ReadonlyArray<{ alias: string; expr: Expression }>;
88
102
  };
89
103
  }
90
104
 
@@ -95,10 +109,10 @@ export interface SelectAst {
95
109
  readonly includes?: ReadonlyArray<IncludeAst>;
96
110
  readonly project: ReadonlyArray<{
97
111
  alias: string;
98
- expr: ColumnRef | IncludeRef | OperationExpr | LiteralExpr;
112
+ expr: Expression | IncludeRef | LiteralExpr;
99
113
  }>;
100
114
  readonly where?: BinaryExpr | ExistsExpr;
101
- readonly orderBy?: ReadonlyArray<{ expr: ColumnRef | OperationExpr; dir: Direction }>;
115
+ readonly orderBy?: ReadonlyArray<{ expr: Expression; dir: Direction }>;
102
116
  readonly limit?: number;
103
117
  }
104
118
 
@@ -1,10 +1,15 @@
1
1
  export {
2
2
  collectColumnRefs,
3
+ expressionFromSource,
3
4
  extractBaseColumnRef,
4
5
  getColumnInfo,
5
6
  getColumnMeta,
6
7
  getOperationExpr,
7
8
  isColumnBuilder,
9
+ isExpressionBuilder,
10
+ isExpressionSource,
8
11
  isOperationExpr,
9
12
  isParamPlaceholder,
13
+ isValueSource,
14
+ toExpression,
10
15
  } from '../utils/guards';
@@ -3,59 +3,71 @@ import { hasAllCapabilities } from '@prisma-next/operations';
3
3
  import { planInvalid } from '@prisma-next/plan';
4
4
  import type { StorageColumn } from '@prisma-next/sql-contract/types';
5
5
  import type { SqlOperationSignature } from '@prisma-next/sql-operations';
6
- import type { BinaryOp, ColumnRef, LiteralExpr, OperationExpr, ParamRef } from './ast/types';
7
- import type { AnyColumnBuilder, ColumnBuilder, OperationTypes, ParamPlaceholder } from './types';
6
+ import type {
7
+ BinaryOp,
8
+ Expression,
9
+ ExpressionSource,
10
+ LiteralExpr,
11
+ OperationExpr,
12
+ ParamRef,
13
+ } from './ast/types';
14
+ import type {
15
+ AnyBinaryBuilder,
16
+ AnyOrderBuilder,
17
+ ColumnBuilder,
18
+ ExpressionBuilder,
19
+ OperationTypes,
20
+ ParamPlaceholder,
21
+ } from './types';
8
22
  import { isParamPlaceholder } from './utils/guards';
9
23
 
10
- function isColumnBuilder(value: unknown): value is AnyColumnBuilder {
24
+ /**
25
+ * Type guard to check if a value is an ExpressionSource (has toExpr method).
26
+ */
27
+ function isExpressionSource(value: unknown): value is ExpressionSource {
11
28
  return (
12
29
  typeof value === 'object' &&
13
30
  value !== null &&
14
- 'kind' in value &&
15
- (value as { kind: unknown }).kind === 'column'
31
+ 'toExpr' in value &&
32
+ typeof (value as ExpressionSource).toExpr === 'function'
16
33
  );
17
34
  }
18
35
 
19
36
  /**
20
- * Executes an operation and returns a column-shaped result object.
37
+ * Executes an operation and returns an ExpressionBuilder.
21
38
  * This is the canonical entrypoint for operation invocation, enabling
22
39
  * future enhancements like telemetry, caching, or tracing.
23
40
  *
41
+ * The returned ExpressionBuilder:
42
+ * - Has `kind: 'expression'` to distinguish it from ColumnBuilder
43
+ * - Contains the operation expression in `expr`
44
+ * - Provides `toExpr()` method to get the Expression
45
+ * - Provides comparison and ordering methods for chaining
46
+ *
24
47
  * @param signature - The operation signature from the registry
25
- * @param selfBuilder - The column builder that the operation is called on
48
+ * @param selfBuilder - The expression source that the operation is called on
26
49
  * @param args - The arguments passed to the operation
27
50
  * @param columnMeta - The metadata of the column the operation is called on
28
- * @returns A column-shaped builder with the operation expression attached
51
+ * @returns An ExpressionBuilder containing the operation expression
29
52
  */
30
53
  function executeOperation(
31
54
  signature: SqlOperationSignature,
32
- selfBuilder: AnyColumnBuilder,
55
+ selfBuilder: ExpressionSource,
33
56
  args: unknown[],
34
57
  columnMeta: StorageColumn,
35
58
  operationRegistry?: OperationRegistry,
36
59
  contractCapabilities?: Record<string, Record<string, boolean>>,
37
- ): AnyColumnBuilder & { _operationExpr?: OperationExpr } {
60
+ ): ExpressionBuilder {
38
61
  if (args.length !== signature.args.length) {
39
62
  throw planInvalid(
40
63
  `Operation ${signature.method} expects ${signature.args.length} arguments, got ${args.length}`,
41
64
  );
42
65
  }
43
66
 
44
- // Check if this column builder has an existing operation expression
45
- const selfBuilderWithExpr = selfBuilder as unknown as {
46
- _operationExpr?: OperationExpr;
47
- table: string;
48
- column: string;
49
- };
50
- const selfExpr: ColumnRef | OperationExpr = selfBuilderWithExpr._operationExpr
51
- ? selfBuilderWithExpr._operationExpr
52
- : {
53
- kind: 'col',
54
- table: selfBuilderWithExpr.table,
55
- column: selfBuilderWithExpr.column,
56
- };
57
-
58
- const operationArgs: Array<ColumnRef | ParamRef | LiteralExpr | OperationExpr> = [];
67
+ // Get the Expression from the self builder using toExpr()
68
+ const selfExpr: Expression = selfBuilder.toExpr();
69
+
70
+ const operationArgs: Array<Expression | ParamRef | LiteralExpr> = [];
59
71
  for (let i = 0; i < args.length; i++) {
60
72
  const arg = args[i];
61
73
  const argSpec = signature.args[i];
@@ -73,25 +85,14 @@ function executeOperation(
73
85
  name: arg.name,
74
86
  });
75
87
  } else if (argSpec.kind === 'typeId') {
76
- if (!isColumnBuilder(arg)) {
77
- throw planInvalid(`Argument ${i} must be a ColumnBuilder`);
78
- }
79
- const colBuilderWithExpr = arg as unknown as {
80
- _operationExpr?: OperationExpr;
81
- table: string;
82
- column: string;
83
- };
84
- // Check if the column builder has an operation expression
85
- if (colBuilderWithExpr._operationExpr) {
86
- operationArgs.push(colBuilderWithExpr._operationExpr);
87
- } else {
88
- // Fall back to raw ColumnRef
89
- operationArgs.push({
90
- kind: 'col',
91
- table: colBuilderWithExpr.table,
92
- column: colBuilderWithExpr.column,
93
- });
88
+ // Accept ExpressionSource (ColumnBuilder or ExpressionBuilder)
89
+ if (!isExpressionSource(arg)) {
90
+ throw planInvalid(
91
+ `Argument ${i} must be an ExpressionSource (ColumnBuilder or ExpressionBuilder)`,
92
+ );
94
93
  }
94
+ // Use toExpr() to get the Expression
95
+ operationArgs.push(arg.toExpr());
95
96
  } else if (argSpec.kind === 'literal') {
96
97
  operationArgs.push({
97
98
  kind: 'literal',
@@ -118,18 +119,19 @@ function executeOperation(
118
119
  }
119
120
  : columnMeta;
120
121
 
121
- const createComparisonMethod = (op: BinaryOp) => (value: ParamPlaceholder) =>
122
- Object.freeze({
123
- kind: 'binary' as const,
124
- op,
125
- left: operationExpr,
126
- right: value,
127
- });
128
-
129
- const baseResult = {
130
- kind: 'column' as const,
131
- table: selfBuilderWithExpr.table,
132
- column: selfBuilderWithExpr.column,
122
+ const createComparisonMethod =
123
+ (op: BinaryOp) =>
124
+ (value: ParamPlaceholder | ExpressionSource): AnyBinaryBuilder =>
125
+ Object.freeze({
126
+ kind: 'binary' as const,
127
+ op,
128
+ left: operationExpr,
129
+ right: value,
130
+ }) as AnyBinaryBuilder;
131
+
132
+ const baseResult: ExpressionBuilder = {
133
+ kind: 'expression' as const,
134
+ expr: operationExpr,
133
135
  get columnMeta() {
134
136
  return returnColumnMeta;
135
137
  },
@@ -139,41 +141,84 @@ function executeOperation(
139
141
  lt: createComparisonMethod('lt'),
140
142
  gte: createComparisonMethod('gte'),
141
143
  lte: createComparisonMethod('lte'),
142
- asc() {
144
+ asc(): AnyOrderBuilder {
143
145
  return Object.freeze({
144
146
  kind: 'order' as const,
145
147
  expr: operationExpr,
146
148
  dir: 'asc' as const,
147
149
  });
148
150
  },
149
- desc() {
151
+ desc(): AnyOrderBuilder {
150
152
  return Object.freeze({
151
153
  kind: 'order' as const,
152
154
  expr: operationExpr,
153
155
  dir: 'desc' as const,
154
156
  });
155
157
  },
156
- _operationExpr: operationExpr,
157
- } as unknown as AnyColumnBuilder & {
158
- _operationExpr?: OperationExpr;
158
+ toExpr(): OperationExpr {
159
+ return operationExpr;
160
+ },
161
+ get __jsType(): unknown {
162
+ return undefined;
163
+ },
159
164
  };
160
165
 
161
166
  // If the return type is a typeId, attach operations for that type
162
167
  if (returnTypeId && operationRegistry) {
163
- const resultWithOps = attachOperationsToColumnBuilder(
164
- baseResult as ColumnBuilder<string, StorageColumn, unknown, Record<string, never>>,
168
+ const resultWithOps = attachOperationsToExpressionBuilder(
169
+ baseResult,
165
170
  returnColumnMeta,
166
171
  operationRegistry,
167
172
  contractCapabilities,
168
- ) as AnyColumnBuilder & {
169
- _operationExpr?: OperationExpr;
170
- };
173
+ );
171
174
  return Object.freeze(resultWithOps);
172
175
  }
173
176
 
174
177
  return Object.freeze(baseResult);
175
178
  }
176
179
 
180
+ /**
181
+ * Attaches operation methods to an ExpressionBuilder for chained operations.
182
+ * When an operation returns a typeId, the result ExpressionBuilder needs
183
+ * operation methods for that type.
184
+ */
185
+ function attachOperationsToExpressionBuilder(
186
+ expressionBuilder: ExpressionBuilder,
187
+ columnMeta: StorageColumn,
188
+ registry: OperationRegistry,
189
+ contractCapabilities?: Record<string, Record<string, boolean>>,
190
+ ): ExpressionBuilder {
191
+ const codecId = columnMeta.codecId;
192
+ if (!codecId) {
193
+ return expressionBuilder;
194
+ }
195
+
196
+ const operations = registry.byType(codecId) as SqlOperationSignature[];
197
+ if (operations.length === 0) {
198
+ return expressionBuilder;
199
+ }
200
+
201
+ const builderWithOps = expressionBuilder as ExpressionBuilder & Record<string, unknown>;
202
+
203
+ for (const operation of operations) {
204
+ if (operation.capabilities && operation.capabilities.length > 0) {
205
+ if (!contractCapabilities) {
206
+ continue;
207
+ }
208
+
209
+ if (!hasAllCapabilities(operation.capabilities, contractCapabilities)) {
210
+ continue;
211
+ }
212
+ }
213
+ // Method sugar: attach operation as a method on the expression builder
214
+ builderWithOps[operation.method] = function (this: ExpressionBuilder, ...args: unknown[]) {
215
+ return executeOperation(operation, this, args, columnMeta, registry, contractCapabilities);
216
+ };
217
+ }
218
+
219
+ return builderWithOps;
220
+ }
221
+
177
222
  export function attachOperationsToColumnBuilder<
178
223
  ColumnName extends string,
179
224
  ColumnMeta extends StorageColumn,
@@ -218,18 +263,12 @@ export function attachOperationsToColumnBuilder<
218
263
  }
219
264
  }
220
265
  // Method sugar: attach operation as a method on the column builder
266
+ // Operations return ExpressionBuilder, not ColumnBuilder
221
267
  (builderWithOps as Record<string, unknown>)[operation.method] = function (
222
268
  this: ColumnBuilder<ColumnName, ColumnMeta, JsType, Record<string, never>>,
223
269
  ...args: unknown[]
224
270
  ) {
225
- return executeOperation(
226
- operation,
227
- this as unknown as ColumnBuilder<string, StorageColumn, unknown>,
228
- args,
229
- columnMeta,
230
- registry,
231
- contractCapabilities,
232
- );
271
+ return executeOperation(operation, this, args, columnMeta, registry, contractCapabilities);
233
272
  };
234
273
  }
235
274
 
package/src/schema.ts CHANGED
@@ -7,11 +7,10 @@ import type {
7
7
  SqlStorage,
8
8
  StorageColumn,
9
9
  } from '@prisma-next/sql-contract/types';
10
- import type { BinaryOp, TableRef } from './ast/types';
10
+ import type { BinaryOp, ColumnRef, ExpressionSource, TableRef } from './ast/types';
11
11
  import { attachOperationsToColumnBuilder } from './operations-registry';
12
12
  import type { QueryLaneContext } from './query-lane-context';
13
13
  import type {
14
- AnyColumnBuilderBase,
15
14
  BinaryBuilder,
16
15
  CodecTypes as CodecTypesType,
17
16
  ColumnBuilder,
@@ -21,7 +20,6 @@ import type {
21
20
  OrderBuilder,
22
21
  ParamPlaceholder,
23
22
  } from './types';
24
- import { isColumnBuilder } from './types';
25
23
 
26
24
  type TableColumns<Table extends { columns: Record<string, StorageColumn> }> = Table['columns'];
27
25
 
@@ -44,7 +42,8 @@ export class ColumnBuilderImpl<
44
42
  ColumnName extends string,
45
43
  ColumnMeta extends StorageColumn,
46
44
  JsType = unknown,
47
- > {
45
+ > implements ExpressionSource
46
+ {
48
47
  readonly kind = 'column' as const;
49
48
 
50
49
  constructor(
@@ -62,64 +61,76 @@ export class ColumnBuilderImpl<
62
61
  return undefined as unknown as JsType;
63
62
  }
64
63
 
64
+ /**
65
+ * Converts this column builder to a ColumnRef expression.
66
+ * This is the canonical way to get an AST node from a builder.
67
+ */
68
+ toExpr(): ColumnRef {
69
+ return Object.freeze({
70
+ kind: 'col' as const,
71
+ table: this.table,
72
+ column: this.column,
73
+ });
74
+ }
75
+
65
76
  private createBinaryBuilder(
66
77
  op: BinaryOp,
67
- value: ParamPlaceholder | AnyColumnBuilderBase,
78
+ value: ParamPlaceholder | ExpressionSource,
68
79
  ): BinaryBuilder<ColumnName, ColumnMeta, JsType> {
69
80
  if (value == null) {
70
- throw planInvalid('Parameter placeholder or column builder required for column comparison');
81
+ throw planInvalid(
82
+ 'Parameter placeholder or expression source required for column comparison',
83
+ );
71
84
  }
72
- if (value.kind === 'param-placeholder' || isColumnBuilder(value)) {
85
+ // Check for ExpressionSource first (has toExpr method)
86
+ if ('toExpr' in value && typeof value.toExpr === 'function') {
73
87
  return Object.freeze({
74
88
  kind: 'binary' as const,
75
89
  op,
76
- left: this as unknown as ColumnBuilder<ColumnName, ColumnMeta, JsType>,
90
+ left: this.toExpr(),
77
91
  right: value,
78
92
  }) as BinaryBuilder<ColumnName, ColumnMeta, JsType>;
79
93
  }
80
- throw planInvalid('Parameter placeholder or column builder required for column comparison');
94
+ // Must be a ParamPlaceholder
95
+ if ('kind' in value && value.kind === 'param-placeholder') {
96
+ return Object.freeze({
97
+ kind: 'binary' as const,
98
+ op,
99
+ left: this.toExpr(),
100
+ right: value,
101
+ }) as BinaryBuilder<ColumnName, ColumnMeta, JsType>;
102
+ }
103
+ throw planInvalid('Parameter placeholder or expression source required for column comparison');
81
104
  }
82
105
 
83
- eq(
84
- value: ParamPlaceholder | AnyColumnBuilderBase,
85
- ): BinaryBuilder<ColumnName, ColumnMeta, JsType> {
106
+ eq(value: ParamPlaceholder | ExpressionSource): BinaryBuilder<ColumnName, ColumnMeta, JsType> {
86
107
  return this.createBinaryBuilder('eq', value);
87
108
  }
88
109
 
89
- neq(
90
- value: ParamPlaceholder | AnyColumnBuilderBase,
91
- ): BinaryBuilder<ColumnName, ColumnMeta, JsType> {
110
+ neq(value: ParamPlaceholder | ExpressionSource): BinaryBuilder<ColumnName, ColumnMeta, JsType> {
92
111
  return this.createBinaryBuilder('neq', value);
93
112
  }
94
113
 
95
- gt(
96
- value: ParamPlaceholder | AnyColumnBuilderBase,
97
- ): BinaryBuilder<ColumnName, ColumnMeta, JsType> {
114
+ gt(value: ParamPlaceholder | ExpressionSource): BinaryBuilder<ColumnName, ColumnMeta, JsType> {
98
115
  return this.createBinaryBuilder('gt', value);
99
116
  }
100
117
 
101
- lt(
102
- value: ParamPlaceholder | AnyColumnBuilderBase,
103
- ): BinaryBuilder<ColumnName, ColumnMeta, JsType> {
118
+ lt(value: ParamPlaceholder | ExpressionSource): BinaryBuilder<ColumnName, ColumnMeta, JsType> {
104
119
  return this.createBinaryBuilder('lt', value);
105
120
  }
106
121
 
107
- gte(
108
- value: ParamPlaceholder | AnyColumnBuilderBase,
109
- ): BinaryBuilder<ColumnName, ColumnMeta, JsType> {
122
+ gte(value: ParamPlaceholder | ExpressionSource): BinaryBuilder<ColumnName, ColumnMeta, JsType> {
110
123
  return this.createBinaryBuilder('gte', value);
111
124
  }
112
125
 
113
- lte(
114
- value: ParamPlaceholder | AnyColumnBuilderBase,
115
- ): BinaryBuilder<ColumnName, ColumnMeta, JsType> {
126
+ lte(value: ParamPlaceholder | ExpressionSource): BinaryBuilder<ColumnName, ColumnMeta, JsType> {
116
127
  return this.createBinaryBuilder('lte', value);
117
128
  }
118
129
 
119
130
  asc(): OrderBuilder<ColumnName, ColumnMeta, JsType> {
120
131
  return Object.freeze({
121
132
  kind: 'order' as const,
122
- expr: this as unknown as ColumnBuilder<ColumnName, ColumnMeta, JsType>,
133
+ expr: this.toExpr(),
123
134
  dir: 'asc' as const,
124
135
  }) as OrderBuilder<ColumnName, ColumnMeta, JsType>;
125
136
  }
@@ -127,7 +138,7 @@ export class ColumnBuilderImpl<
127
138
  desc(): OrderBuilder<ColumnName, ColumnMeta, JsType> {
128
139
  return Object.freeze({
129
140
  kind: 'order' as const,
130
- expr: this as unknown as ColumnBuilder<ColumnName, ColumnMeta, JsType>,
141
+ expr: this.toExpr(),
131
142
  dir: 'desc' as const,
132
143
  }) as OrderBuilder<ColumnName, ColumnMeta, JsType>;
133
144
  }