@prisma/orm-family-sql 8.0.0-rc.12-dev.8 → 8.0.0-rc.12-dev.10

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 (129) hide show
  1. package/dist/{aggregate-descriptor-registry-BaMSvS82.mjs → aggregate-descriptor-registry-CJF2KxUb.mjs} +2 -2
  2. package/dist/{aggregate-descriptor-registry-BaMSvS82.mjs.map → aggregate-descriptor-registry-CJF2KxUb.mjs.map} +1 -1
  3. package/dist/{ast-Cl_w2lbg.d.mts → ast-B9jF6tRJ.d.mts} +3 -3
  4. package/dist/{ast-Cl_w2lbg.d.mts.map → ast-B9jF6tRJ.d.mts.map} +1 -1
  5. package/dist/{ast--wLzFkbt.mjs → ast-Bhj549wG.mjs} +2 -2
  6. package/dist/ast-Bhj549wG.mjs.map +1 -0
  7. package/dist/{authoring-type-constructors-C1ogrr_x-B9lfq5gm.mjs → authoring-type-constructors-C1ogrr_x-D8KVlpwM.mjs} +2 -2
  8. package/dist/{authoring-type-constructors-C1ogrr_x-B9lfq5gm.mjs.map → authoring-type-constructors-C1ogrr_x-D8KVlpwM.mjs.map} +1 -1
  9. package/dist/builder.d.mts +2 -2
  10. package/dist/builder__runtime.d.mts +6 -6
  11. package/dist/builder__runtime.mjs +9 -7
  12. package/dist/builder__runtime.mjs.map +1 -1
  13. package/dist/builder__types.d.mts +2 -2
  14. package/dist/{config-types-DLERgC8A.mjs → config-types-BFnBqnfx.mjs} +2 -2
  15. package/dist/{config-types-DLERgC8A.mjs.map → config-types-BFnBqnfx.mjs.map} +1 -1
  16. package/dist/{contract-builder-IOKzKHhU.mjs → contract-builder-Vu-9o_FQ.mjs} +3 -3
  17. package/dist/{contract-builder-IOKzKHhU.mjs.map → contract-builder-Vu-9o_FQ.mjs.map} +1 -1
  18. package/dist/contract-prisma7__provider.mjs +3 -3
  19. package/dist/contract-psl.mjs +1 -1
  20. package/dist/contract-psl__provider.mjs +2 -2
  21. package/dist/contract-ts.mjs +3 -3
  22. package/dist/contract-ts__config-types.mjs +1 -1
  23. package/dist/contract-ts__contract-builder.mjs +2 -2
  24. package/dist/contract.mjs +1 -1
  25. package/dist/contract__validators.mjs +1 -1
  26. package/dist/{control-BjvN-a2_.mjs → control-DTKBQtcA.mjs} +4 -4
  27. package/dist/{control-BjvN-a2_.mjs.map → control-DTKBQtcA.mjs.map} +1 -1
  28. package/dist/{control-BS-GfNP5.d.mts → control-DcpmxWtu.d.mts} +6 -6
  29. package/dist/{control-BS-GfNP5.d.mts.map → control-DcpmxWtu.d.mts.map} +1 -1
  30. package/dist/{control-adapter-C99J7aEF-jlK7uZyJ.d.mts → control-adapter-C99J7aEF-Bu-VCRbv.d.mts} +4 -4
  31. package/dist/{control-adapter-C99J7aEF-jlK7uZyJ.d.mts.map → control-adapter-C99J7aEF-Bu-VCRbv.d.mts.map} +1 -1
  32. package/dist/control-adapter-D4_Oipv6.d.mts +1 -0
  33. package/dist/{db-BhQdL6Za-C0DS91Ec.d.mts → db-DLjWu9-f-6BG2QArC.d.mts} +7 -8
  34. package/dist/db-DLjWu9-f-6BG2QArC.d.mts.map +1 -0
  35. package/dist/{ddl-types-DrK8E0jL-Cz06w-Hd.d.mts → ddl-types-DD-i-Uj9-D99heD5Z.d.mts} +3 -3
  36. package/dist/{ddl-types-DrK8E0jL-Cz06w-Hd.d.mts.map → ddl-types-DD-i-Uj9-D99heD5Z.d.mts.map} +1 -1
  37. package/dist/{derived-checks-6WZKIUxH-CWip2UN5.mjs → derived-checks-BiClpWj6-chqISMq1.mjs} +8 -8
  38. package/dist/derived-checks-BiClpWj6-chqISMq1.mjs.map +1 -0
  39. package/dist/{diff-B7HTKtCK.d.mts → diff-CHX4XHhC.d.mts} +3 -3
  40. package/dist/{diff-B7HTKtCK.d.mts.map → diff-CHX4XHhC.d.mts.map} +1 -1
  41. package/dist/{expression-DV56tQtp.d.mts → expression-BPoA5eEl.d.mts} +3 -3
  42. package/dist/{expression-DV56tQtp.d.mts.map → expression-BPoA5eEl.d.mts.map} +1 -1
  43. package/dist/{expression-CrGD_4do.mjs → expression-vAEOvq7J.mjs} +2 -2
  44. package/dist/{expression-CrGD_4do.mjs.map → expression-vAEOvq7J.mjs.map} +1 -1
  45. package/dist/family.d.mts +7 -7
  46. package/dist/family.mjs +4 -4
  47. package/dist/family__control-adapter.d.mts +2 -2
  48. package/dist/family__control.d.mts +2 -2
  49. package/dist/family__control.mjs +2 -2
  50. package/dist/family__diff.d.mts +2 -2
  51. package/dist/family__ir.mjs +1 -1
  52. package/dist/family__migration.d.mts +1 -1
  53. package/dist/family__pack.mjs +1 -1
  54. package/dist/family__psl-infer.mjs +1 -1
  55. package/dist/family__runtime.d.mts +1 -1
  56. package/dist/{index-DTvblzjn.d.mts → index-C10GDLBQ.d.mts} +9 -9
  57. package/dist/{index-DTvblzjn.d.mts.map → index-C10GDLBQ.d.mts.map} +1 -1
  58. package/dist/{interpreter-CYD009gd-DK-SbljF.mjs → interpreter-CYD009gd-KeytabKd.mjs} +2 -2
  59. package/dist/{interpreter-CYD009gd-DK-SbljF.mjs.map → interpreter-CYD009gd-KeytabKd.mjs.map} +1 -1
  60. package/dist/{middleware-CHg6zJkn-BXbPG5gs.d.mts → middleware-CuGBptK0-C88HCnh5.d.mts} +3 -3
  61. package/dist/{middleware-CHg6zJkn-BXbPG5gs.d.mts.map → middleware-CuGBptK0-C88HCnh5.d.mts.map} +1 -1
  62. package/dist/middleware-aoqicpDI.d.mts +1 -0
  63. package/dist/{migration-9HfBKBhT.d.mts → migration-BwA1d1OP.d.mts} +2 -2
  64. package/dist/{migration-9HfBKBhT.d.mts.map → migration-BwA1d1OP.d.mts.map} +1 -1
  65. package/dist/orm-client.d.mts +40 -19
  66. package/dist/orm-client.d.mts.map +1 -1
  67. package/dist/orm-client.mjs +161 -46
  68. package/dist/orm-client.mjs.map +1 -1
  69. package/dist/{plan-DVkrl9Pq-CUhH48Gt.d.mts → plan-B7g2kDfQ-Bw0784x6.d.mts} +3 -3
  70. package/dist/plan-B7g2kDfQ-Bw0784x6.d.mts.map +1 -0
  71. package/dist/plan-DiT00Rg8.d.mts +2 -0
  72. package/dist/{prepared-statement-B6zvhJej-CAzfySgB.d.mts → prepared-statement-B6zvhJej-Dl488oBR.d.mts} +13 -13
  73. package/dist/{prepared-statement-B6zvhJej-CAzfySgB.d.mts.map → prepared-statement-B6zvhJej-Dl488oBR.d.mts.map} +1 -1
  74. package/dist/{psl-infer-C06FXwvC.mjs → psl-infer-Df2DrvP-.mjs} +2 -2
  75. package/dist/{psl-infer-C06FXwvC.mjs.map → psl-infer-Df2DrvP-.mjs.map} +1 -1
  76. package/dist/{query-lane-context-BUNC86DS-554MXNHX.d.mts → query-lane-context-Bi1GUXHp-Bo4OTjhW.d.mts} +3 -3
  77. package/dist/{query-lane-context-BUNC86DS-554MXNHX.d.mts.map → query-lane-context-Bi1GUXHp-Bo4OTjhW.d.mts.map} +1 -1
  78. package/dist/query-lane-context-CJNBt8cm.d.mts +1 -0
  79. package/dist/relational-core.d.mts +12 -12
  80. package/dist/relational-core.mjs +4 -4
  81. package/dist/relational-core__aggregate-descriptor-registry.d.mts +1 -1
  82. package/dist/relational-core__aggregate-descriptor-registry.mjs +1 -1
  83. package/dist/relational-core__ast.d.mts +4 -4
  84. package/dist/relational-core__ast.mjs +3 -3
  85. package/dist/relational-core__codec-descriptor-registry.d.mts +2 -2
  86. package/dist/relational-core__contract-free.d.mts +2 -2
  87. package/dist/relational-core__contract-free.mjs +1 -1
  88. package/dist/relational-core__contract-free.mjs.map +1 -1
  89. package/dist/relational-core__expression.d.mts +1 -1
  90. package/dist/relational-core__expression.mjs +1 -1
  91. package/dist/relational-core__middleware.d.mts +2 -2
  92. package/dist/relational-core__plan.d.mts +3 -3
  93. package/dist/relational-core__query-lane-context.d.mts +2 -2
  94. package/dist/relational-core__types.d.mts +2 -2
  95. package/dist/{runtime-BETVTTvU.d.mts → runtime-DYpzLADy.d.mts} +3 -3
  96. package/dist/{runtime-BETVTTvU.d.mts.map → runtime-DYpzLADy.d.mts.map} +1 -1
  97. package/dist/runtime.d.mts +4 -4
  98. package/dist/runtime.mjs +5 -5
  99. package/dist/runtime.mjs.map +1 -1
  100. package/dist/runtime__internal__prepared-query.d.mts +1 -1
  101. package/dist/{sql-contract-serializer-0a4k494z-QYmio7Uz.mjs → sql-contract-serializer-0a4k494z-ClMyRBHo.mjs} +2 -2
  102. package/dist/{sql-contract-serializer-0a4k494z-QYmio7Uz.mjs.map → sql-contract-serializer-0a4k494z-ClMyRBHo.mjs.map} +1 -1
  103. package/dist/{sql-execution-plan-DBvAsaOB-CJwz206K.d.mts → sql-execution-plan-Db0j752I-CI5WbdLi.d.mts} +3 -3
  104. package/dist/sql-execution-plan-Db0j752I-CI5WbdLi.d.mts.map +1 -0
  105. package/dist/{types-BFPRCYGW-DeB_n96N.d.mts → types-BFPRCYGW-BheztqYQ.d.mts} +2 -2
  106. package/dist/{types-BFPRCYGW-DeB_n96N.d.mts.map → types-BFPRCYGW-BheztqYQ.d.mts.map} +1 -1
  107. package/dist/{types-BAhLyUFj-3TARSz8c.mjs → types-BPi4d3WI-D8PIEqBU.mjs} +31 -13
  108. package/dist/types-BPi4d3WI-D8PIEqBU.mjs.map +1 -0
  109. package/dist/{types-_3eY-tTq-DY2fDu2J.d.mts → types-Bcujdkdw-2SDajXRo.d.mts} +6 -6
  110. package/dist/{types-_3eY-tTq-DY2fDu2J.d.mts.map → types-Bcujdkdw-2SDajXRo.d.mts.map} +1 -1
  111. package/dist/{types-YGX78yVc-LY1JQLED.d.mts → types-Yui2yFf6-TP-oRDTX.d.mts} +17 -9
  112. package/dist/types-Yui2yFf6-TP-oRDTX.d.mts.map +1 -0
  113. package/dist/types-nNy0nND_.d.mts +1 -0
  114. package/dist/{validators-CR2v1106.mjs → validators-CSjiy5BN.mjs} +3 -3
  115. package/dist/validators-CSjiy5BN.mjs.map +1 -0
  116. package/package.json +18 -18
  117. package/dist/ast--wLzFkbt.mjs.map +0 -1
  118. package/dist/control-adapter-fsjgABHQ.d.mts +0 -1
  119. package/dist/db-BhQdL6Za-C0DS91Ec.d.mts.map +0 -1
  120. package/dist/derived-checks-6WZKIUxH-CWip2UN5.mjs.map +0 -1
  121. package/dist/middleware-nbYXEk2K.d.mts +0 -1
  122. package/dist/plan-DVkrl9Pq-CUhH48Gt.d.mts.map +0 -1
  123. package/dist/plan-Dh-FnySu.d.mts +0 -2
  124. package/dist/query-lane-context-Cj8AWGMg.d.mts +0 -1
  125. package/dist/sql-execution-plan-DBvAsaOB-CJwz206K.d.mts.map +0 -1
  126. package/dist/types-BAhLyUFj-3TARSz8c.mjs.map +0 -1
  127. package/dist/types-BvpZI6y1.d.mts +0 -1
  128. package/dist/types-YGX78yVc-LY1JQLED.d.mts.map +0 -1
  129. package/dist/validators-CR2v1106.mjs.map +0 -1
@@ -1,9 +1,9 @@
1
1
  import { t as resolveStorageTable } from "./resolve-storage-table-DZsfnzeW.mjs";
2
2
  import { i as isUniqueConstraintViolation } from "./dist-x6jvtkKM.mjs";
3
- import { C as LiteralExpr, D as OrExpr, F as SubqueryExpr, I as TableSource, L as UpdateAst, O as OrderByItem, P as SelectAst, R as WindowFuncExpr, S as ListExpression, T as NullCheckExpr, U as isWhereExpr, V as isAggregateFn, _ as InsertAst, b as JsonArrayAggExpr, c as DeleteAst, f as EqColJoinOn, j as ProjectionItem, k as ParamRef, l as DerivedTableSource, n as AndExpr, o as ColumnRef, p as ExistsExpr, r as BinaryExpr, s as DefaultValueExpr, t as AggregateExpr, v as InsertOnConflict, w as NotExpr, x as JsonObjectExpr, y as JoinAst } from "./types-BAhLyUFj-3TARSz8c.mjs";
3
+ import { C as LiteralExpr, D as OrExpr, F as SubqueryExpr, G as isWhereExpr, I as TableSource, L as UpdateAst, O as OrderByItem, P as SelectAst, R as WindowFuncExpr, S as ListExpression, T as NullCheckExpr, U as isOrderByNulls, V as isAggregateFn, _ as InsertAst, b as JsonArrayAggExpr, c as DeleteAst, f as EqColJoinOn, j as ProjectionItem, k as ParamRef, l as DerivedTableSource, n as AndExpr, o as ColumnRef, p as ExistsExpr, r as BinaryExpr, s as DefaultValueExpr, t as AggregateExpr, v as InsertOnConflict, w as NotExpr, x as JsonObjectExpr, y as JoinAst } from "./types-BPi4d3WI-D8PIEqBU.mjs";
4
4
  import { t as collectOrderedParamRefs } from "./util-DQQgv2j1-D6INZaRG.mjs";
5
- import { n as JsonDocumentProjection, r as NativeJsonValueProjection, t as CodecJsonValueProjection } from "./ast--wLzFkbt.mjs";
6
- import { i as isExpression, o as toExpr } from "./expression-CrGD_4do.mjs";
5
+ import { n as JsonDocumentProjection, r as NativeJsonValueProjection, t as CodecJsonValueProjection } from "./ast-Bhj549wG.mjs";
6
+ import { i as isExpression, o as toExpr } from "./expression-vAEOvq7J.mjs";
7
7
  import { n as codecRefForStorageColumn } from "./codec-descriptor-registry-ECZ4ohtG.mjs";
8
8
  import { structuredError } from "@prisma/orm-framework/utils/structured-error";
9
9
  import { InternalError } from "@prisma/orm-framework/utils/internal-error";
@@ -267,7 +267,7 @@ function resolveThrough(contract, through) {
267
267
  };
268
268
  }
269
269
  function hasExecutionCreateDefault(contract, namespace, table, column) {
270
- return contract.execution?.mutations.defaults.some((mutationDefault) => mutationDefault.ref.namespace === namespace && mutationDefault.ref.table === table && mutationDefault.ref.column === column && mutationDefault.onCreate !== void 0) ?? false;
270
+ return contract.execution?.mutations.defaults.some((mutationDefault) => mutationDefault.ref.namespace === namespace && mutationDefault.ref.entry === table && mutationDefault.ref.field === column && mutationDefault.onCreate !== void 0) ?? false;
271
271
  }
272
272
  const modelRelationsCache = /* @__PURE__ */ new WeakMap();
273
273
  function resolveModelRelations(contract, namespaceId, modelName) {
@@ -589,6 +589,44 @@ function mapResultRows(result, mapper) {
589
589
  };
590
590
  return new AsyncIterableResult(generator());
591
591
  }
592
+ /**
593
+ * A keyset needs a cursor value for every order axis, so each active order must be a plain column without null placement.
594
+ */
595
+ function assertCursorCompatibleOrder(orderBy) {
596
+ (orderBy ?? []).forEach((item, index) => {
597
+ const position = index + 1;
598
+ if (item.expr.kind !== "column-ref") throw ormError("ORM.ARGUMENT_INVALID", `cursor() cannot key on orderBy item ${position}: it orders by an expression rather than a column, and relation orders, relation counts and operation results are not cursorable. Order by the model's own columns to paginate with a cursor.`, { meta: {
599
+ method: "cursor",
600
+ position
601
+ } });
602
+ if (item.nulls !== void 0) throw ormError("ORM.ARGUMENT_INVALID", `cursor() cannot key on orderBy item ${position}: an order with nulls placement is not cursorable. Remove the nulls option to paginate with a cursor.`, { meta: {
603
+ method: "cursor",
604
+ position,
605
+ nulls: item.nulls
606
+ } });
607
+ });
608
+ }
609
+ /**
610
+ * Postgres requires the leading `ORDER BY` items to match the `DISTINCT ON` expressions, so the first `distinctOnCount` items must be plain columns; later items only choose which row represents each group and may be any expression.
611
+ */
612
+ function assertDistinctOnCompatibleOrder(orderBy, distinctOnCount) {
613
+ (orderBy ?? []).slice(0, distinctOnCount).forEach((item, index) => {
614
+ const position = index + 1;
615
+ if (item.expr.kind !== "column-ref") throw ormError("ORM.ARGUMENT_INVALID", `distinctOn() needs its ${distinctOnCount} column(s) as the first orderBy items, but orderBy item ${position} orders by an expression rather than a column. Put the distinctOn columns first; relation orders, relation counts and operation results may follow them.`, { meta: {
616
+ method: "distinctOn",
617
+ position,
618
+ distinctOnCount
619
+ } });
620
+ });
621
+ }
622
+ function checkedOrderByItem(dir, expr, options) {
623
+ const nulls = options?.nulls;
624
+ if (nulls !== void 0 && !isOrderByNulls(nulls)) throw ormError("ORM.ARGUMENT_INVALID", `${dir}() nulls must be "first" or "last"`, { meta: {
625
+ method: dir,
626
+ nulls: String(nulls)
627
+ } });
628
+ return new OrderByItem(expr, dir, nulls);
629
+ }
592
630
  function deriveParamsFromAst(ast) {
593
631
  return { params: collectOrderedParamRefs(ast).map((p) => p.kind === "param-ref" ? p.value : void 0) };
594
632
  }
@@ -753,7 +791,7 @@ function bindProjectionExpr(contract, expr) {
753
791
  return expr.kind === "literal" ? expr : bindExpression(contract, expr);
754
792
  }
755
793
  function bindOrderByItem(contract, orderItem) {
756
- return new OrderByItem(bindExpression(contract, orderItem.expr), orderItem.dir);
794
+ return orderItem.withExpr(bindExpression(contract, orderItem.expr));
757
795
  }
758
796
  function bindJoin(contract, join) {
759
797
  const namespaceId = namespaceCoordinateForSource(join.source);
@@ -810,9 +848,10 @@ function buildLexicographicCursorWhere(tableName, entries) {
810
848
  }
811
849
  function buildCursorWhere(tableName, orderBy, cursor) {
812
850
  if (!cursor || !orderBy || orderBy.length === 0) return;
851
+ assertCursorCompatibleOrder(orderBy);
813
852
  const entries = [];
814
853
  for (const order of orderBy) {
815
- if (order.expr.kind !== "column-ref") continue;
854
+ if (order.expr.kind !== "column-ref") throw new InternalError("assertCursorCompatibleOrder admits only column orders");
816
855
  const column = order.expr.column;
817
856
  const value = cursor[column];
818
857
  if (value === void 0) throw ormError("ORM.CURSOR_VALUE_MISSING", `Missing cursor value for orderBy column "${column}"`, { meta: { column } });
@@ -941,16 +980,34 @@ function hasEntries(value) {
941
980
  function buildAggregateInput(contract, namespaceId, tableName, state, modelName, projection) {
942
981
  const polyInfo = modelName ? resolvePolymorphismInfo(contract, namespaceId, modelName) : void 0;
943
982
  const variantJoins = polyInfo && polyInfo.mtiVariants.length > 0 ? buildMtiJoins(contract, namespaceId, polyInfo, state.variantName, void 0).joins : [];
944
- const { source, where: effectiveWhere } = buildDedupedTableSource(contract, namespaceId, tableName, state, buildStateWhere(contract, tableName, state, { namespaceId }), projection, variantJoins);
983
+ const where = buildStateWhere(contract, tableName, state, { namespaceId });
984
+ const hiddenOrders = hasEntries(state.distinct) ? projectExpressionOrders(tableName, state.orderBy) : void 0;
985
+ const { source, where: effectiveWhere } = buildDedupedTableSource(contract, namespaceId, tableName, state, where, [...projection, ...hiddenOrders?.projection ?? []], variantJoins);
945
986
  let inner = SelectAst.from(source).withProjection(projection);
946
987
  if (!hasEntries(state.distinct) && variantJoins.length > 0) inner = inner.withJoins(variantJoins);
947
988
  if (effectiveWhere) inner = inner.withWhere(effectiveWhere);
948
989
  if (hasEntries(state.distinctOn)) inner = inner.withDistinctOn(state.distinctOn.map((column) => ColumnRef.of(tableName, column)));
949
- if (hasEntries(state.orderBy)) inner = inner.withOrderBy(state.orderBy);
990
+ const orderBy = hiddenOrders?.orderBy ?? state.orderBy;
991
+ if (hasEntries(orderBy)) inner = inner.withOrderBy(orderBy);
950
992
  if (state.limit !== void 0) inner = inner.withLimit(state.limit);
951
993
  if (state.offset !== void 0) inner = inner.withOffset(state.offset);
952
994
  return { source: DerivedTableSource.as(tableName, inner) };
953
995
  }
996
+ /**
997
+ * The dedup wrap exposes only its projection, so an order over an expression (a relation order, a count, an operation result) cannot be evaluated above it. Each such order is projected inside the wrap as a hidden `__order_N` column and the outer order reads that column.
998
+ */
999
+ function projectExpressionOrders(tableName, orderBy) {
1000
+ const projection = [];
1001
+ return {
1002
+ projection,
1003
+ orderBy: (orderBy ?? []).map((item, index) => {
1004
+ if (item.expr.kind === "column-ref") return item;
1005
+ const alias = `__order_${index}`;
1006
+ projection.push(ProjectionItem.of(alias, item.expr));
1007
+ return item.withExpr(ColumnRef.of(tableName, alias));
1008
+ })
1009
+ };
1010
+ }
954
1011
  function predicateComparison(op, left, right) {
955
1012
  const nullable = (right.kind === "list" ? [left, ...right.values] : [left, right]).find((operand) => operand.kind === "prepared-param-ref" && operand.nullable);
956
1013
  if (nullable?.kind !== "prepared-param-ref") return new BinaryExpr(op, left, right);
@@ -1045,11 +1102,11 @@ const COMPARISON_METHODS_META = {
1045
1102
  },
1046
1103
  asc: {
1047
1104
  traits: ["order"],
1048
- create: (left) => () => OrderByItem.asc(left)
1105
+ create: (left) => (options) => checkedOrderByItem("asc", left, options)
1049
1106
  },
1050
1107
  desc: {
1051
1108
  traits: ["order"],
1052
- create: (left) => () => OrderByItem.desc(left)
1109
+ create: (left) => (options) => checkedOrderByItem("desc", left, options)
1053
1110
  },
1054
1111
  isNull: {
1055
1112
  traits: [],
@@ -1157,7 +1214,10 @@ function compileAggregate(contract, aggregates, namespaceId, tableName, state, a
1157
1214
  namespaceId,
1158
1215
  tableName
1159
1216
  } });
1160
- if (state.distinctOn !== void 0 && state.distinctOn.length > 0) assertDistinctOnCapability(contract, "distinctOn");
1217
+ if (state.distinctOn !== void 0 && state.distinctOn.length > 0) {
1218
+ assertDistinctOnCapability(contract, "distinctOn");
1219
+ assertDistinctOnCompatibleOrder(state.orderBy, state.distinctOn.length);
1220
+ }
1161
1221
  const hasPagination = state.limit !== void 0 || state.offset !== void 0;
1162
1222
  const hasDistinct = state.distinct !== void 0 && state.distinct.length > 0 || state.distinctOn !== void 0 && state.distinctOn.length > 0;
1163
1223
  if (hasPagination || hasDistinct) {
@@ -1194,7 +1254,10 @@ function compileGroupedAggregate(contract, aggregates, namespaceId, tableName, p
1194
1254
  namespaceId,
1195
1255
  tableName
1196
1256
  } });
1197
- if (preGroupState.distinctOn !== void 0 && preGroupState.distinctOn.length > 0) assertDistinctOnCapability(contract, "distinctOn");
1257
+ if (preGroupState.distinctOn !== void 0 && preGroupState.distinctOn.length > 0) {
1258
+ assertDistinctOnCapability(contract, "distinctOn");
1259
+ assertDistinctOnCompatibleOrder(preGroupState.orderBy, preGroupState.distinctOn.length);
1260
+ }
1198
1261
  const projection = [...groupByColumns.map((column) => ProjectionItem.of(column, ColumnRef.of(tableName, column), codecRefForStorageColumn(contract.storage, namespaceId, tableName, column))), ...entries.map(([alias, selector]) => {
1199
1262
  const { expr, codec } = toAggregateProjection(contract, aggregates, namespaceId, tableName, selector);
1200
1263
  return ProjectionItem.of(alias, expr, codec);
@@ -1502,7 +1565,7 @@ function buildIncludeOrderArtifacts(relationName, rowAlias, childOrderBy) {
1502
1565
  aggregateOrderBy: hiddenOrderProjection.map((projection, index) => {
1503
1566
  const orderItem = childOrderBy[index];
1504
1567
  if (!orderItem) throw new InternalError(`Missing include order metadata at index ${index}`);
1505
- return new OrderByItem(ColumnRef.of(rowAlias, projection.alias), orderItem.dir);
1568
+ return orderItem.withExpr(ColumnRef.of(rowAlias, projection.alias));
1506
1569
  })
1507
1570
  };
1508
1571
  }
@@ -1648,7 +1711,10 @@ function buildManyToManyJunctionArtifacts(parentLocalRefs, childTableRef, throug
1648
1711
  }
1649
1712
  function buildIncludeChildRowsSelect(contract, aggregates, parentSource, include) {
1650
1713
  const childState = include.nested;
1651
- if (childState.distinctOn !== void 0 && childState.distinctOn.length > 0) assertDistinctOnCapability(contract, "distinctOn");
1714
+ if (childState.distinctOn !== void 0 && childState.distinctOn.length > 0) {
1715
+ assertDistinctOnCapability(contract, "distinctOn");
1716
+ assertDistinctOnCompatibleOrder(childState.orderBy, childState.distinctOn.length);
1717
+ }
1652
1718
  const parentLocalRefs = resolveParentLocalRefs(parentSource, include, localColumnsForRowInclude(include));
1653
1719
  const childSource = resolveChildTableSource(include, parentLocalRefs);
1654
1720
  const childTableAlias = childSource.alias;
@@ -1710,7 +1776,7 @@ function buildIncludeChildRowsSelect(contract, aggregates, parentSource, include
1710
1776
  rankingOrderBy: childOrderBy ?? [],
1711
1777
  rankedAlias
1712
1778
  });
1713
- if (childOrderBy) childRows = childRows.withOrderBy(childOrderBy.map((item, index) => new OrderByItem(ColumnRef.of(rankedAlias, `${include.relationName}__order_${index}`), item.dir)));
1779
+ if (childOrderBy) childRows = childRows.withOrderBy(childOrderBy.map((item, index) => item.withExpr(ColumnRef.of(rankedAlias, `${include.relationName}__order_${index}`))));
1714
1780
  } else if (childOrderBy) childRows = childRows.withOrderBy(childOrderBy);
1715
1781
  if (childState.limit !== void 0) childRows = childRows.withLimit(childState.limit);
1716
1782
  if (childState.offset !== void 0) childRows = childRows.withOffset(childState.offset);
@@ -1754,7 +1820,7 @@ function buildDistinctNonLeafChildRowsSelect(options) {
1754
1820
  rankingOrderBy: childOrderBy ?? [],
1755
1821
  rankedAlias
1756
1822
  });
1757
- if (childOrderBy) innerSelect = innerSelect.withOrderBy(childOrderBy.map((item, index) => new OrderByItem(ColumnRef.of(rankedAlias, `${include.relationName}__order_${index}`), item.dir)));
1823
+ if (childOrderBy) innerSelect = innerSelect.withOrderBy(childOrderBy.map((item, index) => item.withExpr(ColumnRef.of(rankedAlias, `${include.relationName}__order_${index}`))));
1758
1824
  if (childState.limit !== void 0) innerSelect = innerSelect.withLimit(childState.limit);
1759
1825
  if (childState.offset !== void 0) innerSelect = innerSelect.withOffset(childState.offset);
1760
1826
  const distinctAlias = `${include.relationName}__distinct`;
@@ -1821,7 +1887,10 @@ function buildIncludeChildScalarSelect(contract, aggregates, parentSource, inclu
1821
1887
  const childTableAlias = childSource.alias;
1822
1888
  const childTableRef = childSource.tableRef;
1823
1889
  const state = scalar.state;
1824
- if (state.distinctOn !== void 0 && state.distinctOn.length > 0) assertDistinctOnCapability(contract, "distinctOn");
1890
+ if (state.distinctOn !== void 0 && state.distinctOn.length > 0) {
1891
+ assertDistinctOnCapability(contract, "distinctOn");
1892
+ assertDistinctOnCompatibleOrder(state.orderBy, state.distinctOn.length);
1893
+ }
1825
1894
  const childWhere = buildStateWhere(contract, childTableRef, state, {
1826
1895
  filterTableName: include.relatedTableName,
1827
1896
  namespaceId: include.relatedNamespaceId
@@ -1862,7 +1931,7 @@ function buildIncludeChildScalarSelect(contract, aggregates, parentSource, inclu
1862
1931
  rankingOrderBy: remappedOrderBy ?? [],
1863
1932
  rankedAlias
1864
1933
  });
1865
- if (remappedOrderBy !== void 0 && remappedOrderBy.length > 0) inner = inner.withOrderBy(remappedOrderBy.map((item, index) => new OrderByItem(ColumnRef.of(rankedAlias, `${include.relationName}__order_${index}`), item.dir)));
1934
+ if (remappedOrderBy !== void 0 && remappedOrderBy.length > 0) inner = inner.withOrderBy(remappedOrderBy.map((item, index) => item.withExpr(ColumnRef.of(rankedAlias, `${include.relationName}__order_${index}`))));
1866
1935
  } else if (remappedOrderBy !== void 0 && remappedOrderBy.length > 0) inner = inner.withOrderBy(remappedOrderBy);
1867
1936
  if (state.limit !== void 0) inner = inner.withLimit(state.limit);
1868
1937
  if (state.offset !== void 0) inner = inner.withOffset(state.offset);
@@ -1954,7 +2023,10 @@ function buildCorrelatedIncludeProjection(contract, aggregates, parentSource, in
1954
2023
  }
1955
2024
  function buildSelectAst(contract, tableName, state, options) {
1956
2025
  const namespaceId = options.namespaceId;
1957
- if (state.distinctOn !== void 0 && state.distinctOn.length > 0) assertDistinctOnCapability(contract, "distinctOn");
2026
+ if (state.distinctOn !== void 0 && state.distinctOn.length > 0) {
2027
+ assertDistinctOnCapability(contract, "distinctOn");
2028
+ assertDistinctOnCompatibleOrder(state.orderBy, state.distinctOn.length);
2029
+ }
1958
2030
  const projection = [...buildProjection(contract, namespaceId, tableName, state.selectedFields, tableName), ...options.includeProjection ?? []];
1959
2031
  const { source: fromSource, where: effectiveWhere } = buildDedupedTableSource(contract, namespaceId, tableName, state, options.where ?? buildStateWhere(contract, tableName, state, { namespaceId }), resolveTableColumns(contract, namespaceId, tableName).map((column) => ProjectionItem.of(column, ColumnRef.of(tableName, column))));
1960
2032
  let ast = SelectAst.from(fromSource).withProjection(projection);
@@ -2855,41 +2927,82 @@ function createExtensionMethodFactory(selfExpr, entry, context) {
2855
2927
  return methods;
2856
2928
  };
2857
2929
  }
2930
+ const RELATION_ACCESSOR_METHOD_NAMES = /* @__PURE__ */ new Set([
2931
+ "some",
2932
+ "every",
2933
+ "none",
2934
+ "count"
2935
+ ]);
2858
2936
  function createRelationFilterAccessor(context, parentNamespaceId, parentModelName, parentScope, relation) {
2859
2937
  const relatedTableName = resolveModelTableName(context.contract, relation.toNamespace, relation.to);
2938
+ const correlate = () => correlateRelatedRows(context, parentNamespaceId, parentModelName, parentScope, relatedTableName, relation);
2939
+ const filters = {
2940
+ some: (predicate) => buildExistsExpr(context, relation, correlate(), "some", predicate),
2941
+ every: (predicate) => buildExistsExpr(context, relation, correlate(), "every", predicate),
2942
+ none: (predicate) => buildExistsExpr(context, relation, correlate(), "none", predicate)
2943
+ };
2944
+ if (isToOneCardinality(relation.cardinality)) return new Proxy(filters, { get(target, prop) {
2945
+ if (typeof prop !== "string") return void 0;
2946
+ if (Object.hasOwn(target, prop)) return Reflect.get(target, prop);
2947
+ if (RELATION_ACCESSOR_METHOD_NAMES.has(prop)) return void 0;
2948
+ return relatedOrderableField(context, relation, relatedTableName, correlate, prop);
2949
+ } });
2860
2950
  return {
2861
- some: (predicate) => buildExistsExpr(context, parentNamespaceId, parentModelName, parentScope, relatedTableName, relation, {
2862
- mode: "some",
2863
- predicate
2864
- }),
2865
- every: (predicate) => buildExistsExpr(context, parentNamespaceId, parentModelName, parentScope, relatedTableName, relation, {
2866
- mode: "every",
2867
- predicate
2868
- }),
2869
- none: (predicate) => buildExistsExpr(context, parentNamespaceId, parentModelName, parentScope, relatedTableName, relation, {
2870
- mode: "none",
2871
- predicate
2872
- })
2951
+ ...filters,
2952
+ count: (predicate) => createOrderable(() => buildRelationCountExpr(context, relation, correlate(), predicate))
2873
2953
  };
2874
2954
  }
2875
- function buildExistsExpr(context, parentNamespaceId, parentModelName, parentScope, relatedTableName, relation, options) {
2876
- if (hasThrough$1(relation)) return buildManyToManyExistsExpr(context, parentNamespaceId, parentModelName, parentScope, relatedTableName, relation, options);
2955
+ function createOrderable(buildExpr) {
2956
+ return {
2957
+ asc: (options) => checkedOrderByItem("asc", buildExpr(), options),
2958
+ desc: (options) => checkedOrderByItem("desc", buildExpr(), options)
2959
+ };
2960
+ }
2961
+ function relatedOrderableField(context, relation, relatedTableName, correlate, fieldName) {
2962
+ const fieldToColumn = getFieldToColumnMap(context.contract, relation.toNamespace, relation.to);
2963
+ if (!Object.hasOwn(fieldToColumn, fieldName)) return void 0;
2964
+ const columnName = fieldToColumn[fieldName];
2965
+ if (columnName === void 0) return void 0;
2966
+ const column = resolveColumn(context.contract, relation.toNamespace, relatedTableName, columnName);
2967
+ if (!column || !hasTrait(context, column.codecId, "order")) return void 0;
2968
+ return createOrderable(() => {
2969
+ const rows = correlate();
2970
+ return SubqueryExpr.of(rows.source.withProjection([ProjectionItem.of(columnName, rows.childScope.current.column(columnName))]).withWhere(rows.correlation));
2971
+ });
2972
+ }
2973
+ function hasTrait(context, codecId, trait) {
2974
+ return (context.codecDescriptors.descriptorFor(codecId)?.traits ?? []).includes(trait);
2975
+ }
2976
+ function buildRelationCountExpr(context, relation, rows, predicate) {
2977
+ const childWhere = toRelationWhereExpr(context, relation.toNamespace, relation.to, predicate, rows.childScope);
2978
+ return SubqueryExpr.of(rows.source.withProjection([ProjectionItem.of("count", plainAggregateExpr("count", void 0))]).withWhere(childWhere ? and(rows.correlation, childWhere) : rows.correlation));
2979
+ }
2980
+ function correlateRelatedRows(context, parentNamespaceId, parentModelName, parentScope, relatedTableName, relation) {
2981
+ if (hasThrough$1(relation)) {
2982
+ const { through } = relation;
2983
+ const { childScope, junctionBinding } = parentScope.forManyToManyRelation(relation.toNamespace, relatedTableName, through.namespaceId, through.table);
2984
+ const junctionJoinOn = buildPairedColumnExprs(junctionBinding, through.childColumns, childScope.current, through.targetColumns);
2985
+ const parentLocalColumns = relation.on.localFields.map((field) => resolveFieldToColumn(context.contract, parentNamespaceId, parentModelName, field));
2986
+ return {
2987
+ childScope,
2988
+ source: SelectAst.from(childScope.current.tableSource(context.contract)).withJoins([JoinAst.inner(junctionBinding.tableSource(context.contract), junctionJoinOn)]),
2989
+ correlation: buildPairedColumnExprs(junctionBinding, through.parentColumns, parentScope.current, parentLocalColumns),
2990
+ keyColumn: firstJoinColumn(through.targetColumns, "targetColumns")
2991
+ };
2992
+ }
2877
2993
  const childScope = parentScope.forRelation(relation.toNamespace, relatedTableName);
2878
- const filterPlan = planRelationFilterMode(buildJoinWhere(context.contract, parentNamespaceId, parentModelName, parentScope.current, childScope.current, relation), toRelationWhereExpr(context, relation.toNamespace, relation.to, options.predicate, childScope), options.mode);
2879
- if (filterPlan.kind === "constantTrue") return AndExpr.true();
2880
- const selectProjectionColumn = firstTargetColumn(context.contract, relation) ?? "id";
2881
- const subquery = SelectAst.from(childScope.current.tableSource(context.contract)).withProjection([ProjectionItem.of("_exists", childScope.current.column(selectProjectionColumn))]).withWhere(filterPlan.where);
2882
- return filterPlan.notExists ? ExistsExpr.notExists(subquery) : ExistsExpr.exists(subquery);
2994
+ return {
2995
+ childScope,
2996
+ source: SelectAst.from(childScope.current.tableSource(context.contract)),
2997
+ correlation: buildJoinWhere(context.contract, parentNamespaceId, parentModelName, parentScope.current, childScope.current, relation),
2998
+ keyColumn: firstTargetColumn(context.contract, relation) ?? "id"
2999
+ };
2883
3000
  }
2884
- function buildManyToManyExistsExpr(context, parentNamespaceId, parentModelName, parentScope, relatedTableName, relation, options) {
2885
- const { through } = relation;
2886
- const { childScope, junctionBinding } = parentScope.forManyToManyRelation(relation.toNamespace, relatedTableName, through.namespaceId, through.table);
2887
- const junctionJoinOn = buildPairedColumnExprs(junctionBinding, through.childColumns, childScope.current, through.targetColumns);
2888
- const parentLocalColumns = relation.on.localFields.map((field) => resolveFieldToColumn(context.contract, parentNamespaceId, parentModelName, field));
2889
- const filterPlan = planRelationFilterMode(buildPairedColumnExprs(junctionBinding, through.parentColumns, parentScope.current, parentLocalColumns), toRelationWhereExpr(context, relation.toNamespace, relation.to, options.predicate, childScope), options.mode);
3001
+ function buildExistsExpr(context, relation, rows, mode, predicate) {
3002
+ const childWhere = toRelationWhereExpr(context, relation.toNamespace, relation.to, predicate, rows.childScope);
3003
+ const filterPlan = planRelationFilterMode(rows.correlation, childWhere, mode);
2890
3004
  if (filterPlan.kind === "constantTrue") return AndExpr.true();
2891
- const firstTargetCol = firstJoinColumn(through.targetColumns, "targetColumns");
2892
- const subquery = SelectAst.from(childScope.current.tableSource(context.contract)).withJoins([JoinAst.inner(junctionBinding.tableSource(context.contract), junctionJoinOn)]).withProjection([ProjectionItem.of("_exists", childScope.current.column(firstTargetCol))]).withWhere(filterPlan.where);
3005
+ const subquery = rows.source.withProjection([ProjectionItem.of("_exists", rows.childScope.current.column(rows.keyColumn))]).withWhere(filterPlan.where);
2893
3006
  return filterPlan.notExists ? ExistsExpr.notExists(subquery) : ExistsExpr.exists(subquery);
2894
3007
  }
2895
3008
  function planRelationFilterMode(joinWhere, childWhere, mode) {
@@ -4068,6 +4181,7 @@ var CollectionImpl = class CollectionImpl {
4068
4181
  * ```
4069
4182
  */
4070
4183
  cursor(cursorValues) {
4184
+ assertCursorCompatibleOrder(this.state.orderBy);
4071
4185
  const mappedCursor = mapCursorValuesToColumns(this.contract, this.namespaceId, this.modelName, cursorValues);
4072
4186
  if (Object.keys(mappedCursor).length === 0) return blindCast(this);
4073
4187
  return this.#clone({ cursor: mappedCursor });
@@ -4105,6 +4219,7 @@ var CollectionImpl = class CollectionImpl {
4105
4219
  */
4106
4220
  distinctOn(...fields) {
4107
4221
  assertDistinctOnCapability(this.contract, "distinctOn");
4222
+ assertDistinctOnCompatibleOrder(this.state.orderBy, fields.length);
4108
4223
  const distinctOnFields = mapFieldsToColumns(this.contract, this.namespaceId, this.modelName, fields);
4109
4224
  return this.#clone({
4110
4225
  distinct: void 0,