@prisma/orm-family-sql 8.0.0-rc.14-dev.42 → 8.0.0-rc.14-dev.44

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 (132) hide show
  1. package/dist/{aggregate-descriptor-registry-B88lvGQB.mjs → aggregate-descriptor-registry-DrJ1vHEo.mjs} +2 -2
  2. package/dist/{aggregate-descriptor-registry-B88lvGQB.mjs.map → aggregate-descriptor-registry-DrJ1vHEo.mjs.map} +1 -1
  3. package/dist/{ast-DOubq2En.mjs → ast-DFvrXEbF.mjs} +2 -2
  4. package/dist/ast-DFvrXEbF.mjs.map +1 -0
  5. package/dist/{ast-DWgP3Fnu.d.mts → ast-fsQdXFSV.d.mts} +3 -3
  6. package/dist/{ast-DWgP3Fnu.d.mts.map → ast-fsQdXFSV.d.mts.map} +1 -1
  7. package/dist/{authoring-entity-types-CZ-vdwYS-BDKo-VHB.d.mts → authoring-entity-types-CZ-vdwYS-Bq3LXsCn.d.mts} +2 -2
  8. package/dist/{authoring-entity-types-CZ-vdwYS-BDKo-VHB.d.mts.map → authoring-entity-types-CZ-vdwYS-Bq3LXsCn.d.mts.map} +1 -1
  9. package/dist/{authoring-type-constructors-dihiQslc-BcIPoPEn.mjs → authoring-type-constructors-dihiQslc-DqtjQyqj.mjs} +2 -2
  10. package/dist/{authoring-type-constructors-dihiQslc-BcIPoPEn.mjs.map → authoring-type-constructors-dihiQslc-DqtjQyqj.mjs.map} +1 -1
  11. package/dist/builder.d.mts +2 -2
  12. package/dist/builder__runtime.d.mts +6 -6
  13. package/dist/builder__runtime.mjs +2 -2
  14. package/dist/builder__types.d.mts +2 -2
  15. package/dist/{config-types-BvoqAKkw.mjs → config-types-CPTtyHK8.mjs} +2 -2
  16. package/dist/{config-types-BvoqAKkw.mjs.map → config-types-CPTtyHK8.mjs.map} +1 -1
  17. package/dist/{config-types-LClcQOkt.d.mts → config-types-Cag6qJnA.d.mts} +2 -2
  18. package/dist/{config-types-LClcQOkt.d.mts.map → config-types-Cag6qJnA.d.mts.map} +1 -1
  19. package/dist/{contract-builder-DoT-AH8l.d.mts → contract-builder-BaJMQFAc.d.mts} +17 -5
  20. package/dist/contract-builder-BaJMQFAc.d.mts.map +1 -0
  21. package/dist/{contract-builder-BRrG-DWN.mjs → contract-builder-Dy172HD2.mjs} +3 -3
  22. package/dist/{contract-builder-BRrG-DWN.mjs.map → contract-builder-Dy172HD2.mjs.map} +1 -1
  23. package/dist/contract-prisma7__provider.mjs +3 -3
  24. package/dist/contract-psl.d.mts +1 -1
  25. package/dist/contract-psl.mjs +1 -1
  26. package/dist/contract-psl__attribute-specs.d.mts +2 -2
  27. package/dist/contract-psl__attribute-specs.mjs +1 -1
  28. package/dist/contract-psl__provider.mjs +2 -2
  29. package/dist/contract-ts.d.mts +4 -4
  30. package/dist/contract-ts.mjs +4 -4
  31. package/dist/contract-ts__config-types.d.mts +1 -1
  32. package/dist/contract-ts__config-types.mjs +1 -1
  33. package/dist/contract-ts__contract-builder.d.mts +3 -3
  34. package/dist/contract-ts__contract-builder.mjs +3 -3
  35. package/dist/{control-C4PkND9K.mjs → control-CMe5ABYI.mjs} +3 -3
  36. package/dist/{control-C4PkND9K.mjs.map → control-CMe5ABYI.mjs.map} +1 -1
  37. package/dist/{control-BThycYAG.d.mts → control-D18L8cFa.d.mts} +7 -7
  38. package/dist/{control-BThycYAG.d.mts.map → control-D18L8cFa.d.mts.map} +1 -1
  39. package/dist/control-adapter-Ciule8Fh.d.mts +1 -0
  40. package/dist/{control-adapter-CkFfBVei-D8yZvwK7.d.mts → control-adapter-CkFfBVei-gLS9b87G.d.mts} +4 -4
  41. package/dist/{control-adapter-CkFfBVei-D8yZvwK7.d.mts.map → control-adapter-CkFfBVei-gLS9b87G.d.mts.map} +1 -1
  42. package/dist/{db-CJxU3aL_-CMuiIKs5.d.mts → db-CJxU3aL_-CM2IReAK.d.mts} +6 -6
  43. package/dist/{db-CJxU3aL_-CMuiIKs5.d.mts.map → db-CJxU3aL_-CM2IReAK.d.mts.map} +1 -1
  44. package/dist/{ddl-types-BT_bz9ck-BjAW4tq0.d.mts → ddl-types-DtKZjNtN-6TxFf4bH.d.mts} +3 -3
  45. package/dist/{ddl-types-BT_bz9ck-BjAW4tq0.d.mts.map → ddl-types-DtKZjNtN-6TxFf4bH.d.mts.map} +1 -1
  46. package/dist/{derived-checks-CsB3zLJ--C7ymzzbW.mjs → derived-checks-DAbro9yn-DtEowq-J.mjs} +6 -6
  47. package/dist/{derived-checks-CsB3zLJ--C7ymzzbW.mjs.map → derived-checks-DAbro9yn-DtEowq-J.mjs.map} +1 -1
  48. package/dist/{derived-checks-DPdD01O0-CABDLeK0.d.mts → derived-checks-DpPkO6Dt-BituyKFg.d.mts} +2 -2
  49. package/dist/derived-checks-DpPkO6Dt-BituyKFg.d.mts.map +1 -0
  50. package/dist/{diff-CN8CxYDc.d.mts → diff-Bg9o9CgK.d.mts} +3 -3
  51. package/dist/{diff-CN8CxYDc.d.mts.map → diff-Bg9o9CgK.d.mts.map} +1 -1
  52. package/dist/{expression-B-9RZQN9.d.mts → expression-B-QXMOmY.d.mts} +3 -3
  53. package/dist/{expression-B-9RZQN9.d.mts.map → expression-B-QXMOmY.d.mts.map} +1 -1
  54. package/dist/{expression-gmLQa4Ie.mjs → expression-JOe6lo4g.mjs} +2 -2
  55. package/dist/{expression-gmLQa4Ie.mjs.map → expression-JOe6lo4g.mjs.map} +1 -1
  56. package/dist/family.d.mts +7 -7
  57. package/dist/family.mjs +1 -1
  58. package/dist/family__control-adapter.d.mts +2 -2
  59. package/dist/family__control.d.mts +2 -2
  60. package/dist/family__control.mjs +1 -1
  61. package/dist/family__diff.d.mts +2 -2
  62. package/dist/family__migration.d.mts +1 -1
  63. package/dist/family__pack.d.mts +1 -1
  64. package/dist/family__pack.mjs +2 -2
  65. package/dist/{index-NVxwovsn.d.mts → index-Z2FIIMxv.d.mts} +9 -9
  66. package/dist/{index-NVxwovsn.d.mts.map → index-Z2FIIMxv.d.mts.map} +1 -1
  67. package/dist/{interpreter-D50jf6Dd-DQMtcGPt.mjs → interpreter-D50jf6Dd-BW-Bj8Qr.mjs} +3 -3
  68. package/dist/{interpreter-D50jf6Dd-DQMtcGPt.mjs.map → interpreter-D50jf6Dd-BW-Bj8Qr.mjs.map} +1 -1
  69. package/dist/middleware-BFoORv3y.d.mts +1 -0
  70. package/dist/{middleware-DAmCZlPN-B8QEPIUy.d.mts → middleware-mLwvcOLS-6Y52seRP.d.mts} +3 -3
  71. package/dist/{middleware-DAmCZlPN-B8QEPIUy.d.mts.map → middleware-mLwvcOLS-6Y52seRP.d.mts.map} +1 -1
  72. package/dist/{migration-K_EPNCmR.d.mts → migration-o-g1rSb-.d.mts} +2 -2
  73. package/dist/{migration-K_EPNCmR.d.mts.map → migration-o-g1rSb-.d.mts.map} +1 -1
  74. package/dist/orm-client.d.mts +223 -31
  75. package/dist/orm-client.d.mts.map +1 -1
  76. package/dist/orm-client.mjs +469 -47
  77. package/dist/orm-client.mjs.map +1 -1
  78. package/dist/{pack-B-_m58dV.d.mts → pack-l0vLQrO8.d.mts} +2 -2
  79. package/dist/{pack-B-_m58dV.d.mts.map → pack-l0vLQrO8.d.mts.map} +1 -1
  80. package/dist/plan-CmfWjqtI.d.mts +2 -0
  81. package/dist/{plan-1wnpBALU-CkFF8oIz.d.mts → plan-cGEaSXHv-2F5y-Dpy.d.mts} +3 -3
  82. package/dist/plan-cGEaSXHv-2F5y-Dpy.d.mts.map +1 -0
  83. package/dist/{prepared-statement-YtgdlN7e-BJzjum7z.d.mts → prepared-statement-YtgdlN7e-BU4UQxB5.d.mts} +13 -13
  84. package/dist/{prepared-statement-YtgdlN7e-BJzjum7z.d.mts.map → prepared-statement-YtgdlN7e-BU4UQxB5.d.mts.map} +1 -1
  85. package/dist/{psl-column-resolution-BegCa1-t-o2A6uWWC.d.mts → psl-column-resolution-BegCa1-t-1XiYCC7t.d.mts} +2 -2
  86. package/dist/{psl-column-resolution-BegCa1-t-o2A6uWWC.d.mts.map → psl-column-resolution-BegCa1-t-1XiYCC7t.d.mts.map} +1 -1
  87. package/dist/{psl-field-resolution-Bi-CSeoQ-BjACY_53.mjs → psl-field-resolution-Bi-CSeoQ-Do_5hZ8Z.mjs} +2 -2
  88. package/dist/{psl-field-resolution-Bi-CSeoQ-BjACY_53.mjs.map → psl-field-resolution-Bi-CSeoQ-Do_5hZ8Z.mjs.map} +1 -1
  89. package/dist/{query-lane-context-Ft8I-pge-nABTUotc.d.mts → query-lane-context-CJoNBspB-Ylhia3fC.d.mts} +3 -3
  90. package/dist/{query-lane-context-Ft8I-pge-nABTUotc.d.mts.map → query-lane-context-CJoNBspB-Ylhia3fC.d.mts.map} +1 -1
  91. package/dist/query-lane-context-qK5s2okl.d.mts +1 -0
  92. package/dist/relational-core.d.mts +12 -12
  93. package/dist/relational-core.mjs +4 -4
  94. package/dist/relational-core__aggregate-descriptor-registry.d.mts +1 -1
  95. package/dist/relational-core__aggregate-descriptor-registry.mjs +1 -1
  96. package/dist/relational-core__ast.d.mts +4 -4
  97. package/dist/relational-core__ast.mjs +3 -3
  98. package/dist/relational-core__codec-descriptor-registry.d.mts +2 -2
  99. package/dist/relational-core__contract-free.d.mts +2 -2
  100. package/dist/relational-core__contract-free.mjs +1 -1
  101. package/dist/relational-core__contract-free.mjs.map +1 -1
  102. package/dist/relational-core__expression.d.mts +1 -1
  103. package/dist/relational-core__expression.mjs +1 -1
  104. package/dist/relational-core__middleware.d.mts +2 -2
  105. package/dist/relational-core__plan.d.mts +3 -3
  106. package/dist/relational-core__query-lane-context.d.mts +2 -2
  107. package/dist/relational-core__types.d.mts +2 -2
  108. package/dist/runtime.d.mts +4 -4
  109. package/dist/runtime.mjs +2 -2
  110. package/dist/runtime__internal__prepared-query.d.mts +1 -1
  111. package/dist/{sql-execution-plan-CdlkkwtB-NuamyL5f.d.mts → sql-execution-plan-C7XauPPu-BMi8hJlv.d.mts} +3 -3
  112. package/dist/sql-execution-plan-C7XauPPu-BMi8hJlv.d.mts.map +1 -0
  113. package/dist/types-14L6c26e.d.mts +1 -0
  114. package/dist/{types-0xZ8asKQ-tfwe3lxh.d.mts → types-BJQcLx-8-DSnaugR4.d.mts} +6 -6
  115. package/dist/{types-0xZ8asKQ-tfwe3lxh.d.mts.map → types-BJQcLx-8-DSnaugR4.d.mts.map} +1 -1
  116. package/dist/{types-CvuS68sy-Cj3SvUKo.d.mts → types-CvuS68sy-Dip2oI3M.d.mts} +2 -2
  117. package/dist/{types-CvuS68sy-Cj3SvUKo.d.mts.map → types-CvuS68sy-Dip2oI3M.d.mts.map} +1 -1
  118. package/dist/{types-C9UR53Lv-BF-_alNk.mjs → types-NTQsD2MS-DAP2yVDn.mjs} +3 -3
  119. package/dist/{types-C9UR53Lv-BF-_alNk.mjs.map → types-NTQsD2MS-DAP2yVDn.mjs.map} +1 -1
  120. package/dist/{types-CqwI8eGx-AYan1yI4.d.mts → types-Sh5HuaZE-C8I29pGQ.d.mts} +4 -3
  121. package/dist/{types-CqwI8eGx-AYan1yI4.d.mts.map → types-Sh5HuaZE-C8I29pGQ.d.mts.map} +1 -1
  122. package/package.json +18 -18
  123. package/dist/ast-DOubq2En.mjs.map +0 -1
  124. package/dist/contract-builder-DoT-AH8l.d.mts.map +0 -1
  125. package/dist/control-adapter-BUyIei4U.d.mts +0 -1
  126. package/dist/derived-checks-DPdD01O0-CABDLeK0.d.mts.map +0 -1
  127. package/dist/middleware-BAA8rimP.d.mts +0 -1
  128. package/dist/plan-1wnpBALU-CkFF8oIz.d.mts.map +0 -1
  129. package/dist/plan-BCQYGXrJ.d.mts +0 -2
  130. package/dist/query-lane-context-CEYIBLlG.d.mts +0 -1
  131. package/dist/sql-execution-plan-CdlkkwtB-NuamyL5f.d.mts.map +0 -1
  132. package/dist/types-DkRYdSXK.d.mts +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 { A as ParamRef, C as LiteralExpr, E as NullCheckExpr, F as SelectAst, H as isAggregateFn, I as SubqueryExpr, K as isWhereExpr, L as TableSource, M as ProjectionItem, O as OrExpr, R as UpdateAst, S as ListExpression, T as NotExpr, W as isOrderByNulls, _ as InsertAst, b as JsonArrayAggExpr, c as DeleteAst, f as EqColJoinOn, k as OrderByItem, l as DerivedTableSource, n as AndExpr, o as ColumnRef, p as ExistsExpr, r as BinaryExpr, s as DefaultValueExpr, t as AggregateExpr, v as InsertOnConflict, x as JsonObjectExpr, y as JoinAst, z as WindowFuncExpr } from "./types-C9UR53Lv-BF-_alNk.mjs";
3
+ import { A as ParamRef, C as LiteralExpr, E as NullCheckExpr, F as SelectAst, G as isOrderByNulls, I as SubqueryExpr, L as TableSource, M as ProjectionItem, O as OrExpr, R as UpdateAst, S as ListExpression, T as NotExpr, U as isAggregateFn, V as checkLimitOffset, W as isOrderByDirection, _ as InsertAst, b as JsonArrayAggExpr, c as DeleteAst, f as EqColJoinOn, k as OrderByItem, l as DerivedTableSource, n as AndExpr, o as ColumnRef, p as ExistsExpr, q as isWhereExpr, r as BinaryExpr, s as DefaultValueExpr, t as AggregateExpr, v as InsertOnConflict, x as JsonObjectExpr, y as JoinAst, z as WindowFuncExpr } from "./types-NTQsD2MS-DAP2yVDn.mjs";
4
4
  import { t as collectOrderedParamRefs } from "./util-BBgcP3gI-XJBkxo1K.mjs";
5
- import { n as JsonDocumentProjection, r as NativeJsonValueProjection, t as CodecJsonValueProjection } from "./ast-DOubq2En.mjs";
6
- import { i as isExpression, o as toExpr } from "./expression-gmLQa4Ie.mjs";
5
+ import { n as JsonDocumentProjection, r as NativeJsonValueProjection, t as CodecJsonValueProjection } from "./ast-DFvrXEbF.mjs";
6
+ import { i as isExpression, o as toExpr } from "./expression-JOe6lo4g.mjs";
7
7
  import { n as codecRefForStorageColumn } from "./codec-descriptor-registry-DoGFktu5.mjs";
8
8
  import { structuredError } from "@prisma/orm-framework/utils/structured-error";
9
9
  import { blindCast, castAs } from "@prisma/orm-framework/utils/casts";
@@ -589,6 +589,15 @@ function mapResultRows(result, mapper) {
589
589
  };
590
590
  return new AsyncIterableResult(generator());
591
591
  }
592
+ function resolveColumn(contract, namespaceId, tableName, columnName) {
593
+ return resolveTableForContract(contract, namespaceId, tableName)?.table.columns[columnName];
594
+ }
595
+ function codecTraits(context, codecId) {
596
+ return context.codecDescriptors.descriptorFor(codecId)?.traits ?? [];
597
+ }
598
+ function hasTrait(context, codecId, trait) {
599
+ return codecTraits(context, codecId).includes(trait);
600
+ }
592
601
  /**
593
602
  * A keyset needs a cursor value for every order axis, so each active order must be a plain column without null placement.
594
603
  */
@@ -2440,7 +2449,7 @@ function resolveIncludedColumnBinding(contract, context, include, key) {
2440
2449
  };
2441
2450
  }
2442
2451
  function resolveIncludedColumnRef(contract, include, key) {
2443
- const baseColumn = resolveStorageColumn(contract, include.relatedNamespaceId, include.relatedTableName, key);
2452
+ const baseColumn = resolveColumn(contract, include.relatedNamespaceId, include.relatedTableName, key);
2444
2453
  if (baseColumn) return {
2445
2454
  table: include.relatedTableName,
2446
2455
  column: key,
@@ -2452,7 +2461,7 @@ function resolveIncludedColumnRef(contract, include, key) {
2452
2461
  const prefix = `${variant.table}__`;
2453
2462
  if (!key.startsWith(prefix)) continue;
2454
2463
  const column = key.slice(prefix.length);
2455
- const variantColumn = resolveStorageColumn(contract, include.relatedNamespaceId, variant.table, column);
2464
+ const variantColumn = resolveColumn(contract, include.relatedNamespaceId, variant.table, column);
2456
2465
  if (variantColumn) return {
2457
2466
  table: variant.table,
2458
2467
  column,
@@ -2460,9 +2469,6 @@ function resolveIncludedColumnRef(contract, include, key) {
2460
2469
  };
2461
2470
  }
2462
2471
  }
2463
- function resolveStorageColumn(contract, namespaceId, tableName, columnName) {
2464
- return contract.storage.namespaces[namespaceId]?.entries.table?.[tableName]?.columns[columnName];
2465
- }
2466
2472
  function decodeIncludedColumnValue(ref, codecId, codec, value) {
2467
2473
  if (ref.storageColumn.many !== false) {
2468
2474
  if (!Array.isArray(value)) wrapIncludedDecodeFailure(/* @__PURE__ */ new TypeError(`expected an array from the driver for many-typed column, got ${typeof value}`), ref, codecId);
@@ -2737,7 +2743,7 @@ function shorthandToWhereExpr(context, namespaceId, modelName, filters) {
2737
2743
  function assertFieldHasEqualityTrait(context, namespaceId, modelName, fieldName) {
2738
2744
  const fieldType = modelOf(context.contract, namespaceId, modelName)?.fields?.[fieldName]?.type;
2739
2745
  const codecId = fieldType?.kind === "scalar" ? fieldType.codecId : void 0;
2740
- if (!(codecId ? context.codecDescriptors.descriptorFor(codecId)?.traits ?? [] : []).includes("equality")) throw ormError("ORM.FILTER_UNSUPPORTED", `Shorthand filter on "${modelName}.${fieldName}": field does not support equality comparisons`, { meta: {
2746
+ if (codecId === void 0 || !hasTrait(context, codecId, "equality")) throw ormError("ORM.FILTER_UNSUPPORTED", `Shorthand filter on "${modelName}.${fieldName}": field does not support equality comparisons`, { meta: {
2741
2747
  model: modelName,
2742
2748
  field: fieldName,
2743
2749
  trait: "equality"
@@ -2874,26 +2880,12 @@ function createModelAccessorInScope(context, namespaceId, modelName, variantName
2874
2880
  const columnName = variantField?.column ?? fieldToColumn[prop] ?? prop;
2875
2881
  const column = resolveColumn(contract, namespaceId, resolvedTable, columnName);
2876
2882
  if (!column) return;
2877
- const traits = context.codecDescriptors.descriptorFor(column.codecId)?.traits ?? [];
2883
+ const traits = codecTraits(context, column.codecId);
2878
2884
  const operations = opsByCodecId.get(column.codecId) ?? [];
2879
2885
  const codec = codecRefForStorageColumn(contract.storage, namespaceId, resolvedTable, columnName);
2880
2886
  return createScalarFieldAccessor(fieldBinding, columnName, column.codecId, column.nullable, codec, traits, operations, context);
2881
2887
  } }));
2882
2888
  }
2883
- function resolveColumn(contract, namespaceId, tableName, columnName) {
2884
- let table;
2885
- try {
2886
- table = storageTableForContract(contract, namespaceId, tableName);
2887
- } catch {
2888
- return;
2889
- }
2890
- const column = table.columns[columnName];
2891
- if (!column) return void 0;
2892
- return {
2893
- codecId: column.codecId,
2894
- nullable: column.nullable
2895
- };
2896
- }
2897
2889
  function createScalarFieldAccessor(tableBinding, columnName, codecId, nullable, codec, traits, operations, context) {
2898
2890
  const column = tableBinding.column(columnName);
2899
2891
  const comparisonEntries = [];
@@ -2917,7 +2909,7 @@ function createExtensionMethodFactory(selfExpr, entry, context) {
2917
2909
  return (...args) => {
2918
2910
  const result = blindCast(entry.impl)(selfExpr, ...args);
2919
2911
  const returnCodecId = result.returnType.codecId;
2920
- const returnTraits = context.codecDescriptors.descriptorFor(returnCodecId)?.traits ?? [];
2912
+ const returnTraits = codecTraits(context, returnCodecId);
2921
2913
  if (returnTraits.includes("boolean")) return result.buildAst();
2922
2914
  const resultAst = result.buildAst();
2923
2915
  const returnCodec = { codecId: returnCodecId };
@@ -2972,9 +2964,6 @@ function relatedOrderableField(context, relation, relatedTableName, correlate, f
2972
2964
  return SubqueryExpr.of(rows.source.withProjection([ProjectionItem.of(columnName, rows.childScope.current.column(columnName))]).withWhere(rows.correlation));
2973
2965
  });
2974
2966
  }
2975
- function hasTrait(context, codecId, trait) {
2976
- return (context.codecDescriptors.descriptorFor(codecId)?.traits ?? []).includes(trait);
2977
- }
2978
2967
  function buildRelationCountExpr(context, relation, rows, predicate) {
2979
2968
  const childWhere = toRelationWhereExpr(context, relation.toNamespace, relation.to, predicate, rows.childScope);
2980
2969
  return SubqueryExpr.of(rows.source.withProjection([ProjectionItem.of("count", plainAggregateExpr("count", void 0))]).withWhere(childWhere ? and(rows.correlation, childWhere) : rows.correlation));
@@ -3847,6 +3836,303 @@ function getRelationDefinitions(contract, namespaceId, modelName) {
3847
3836
  function toFieldName(contract, namespaceId, modelName, columnName) {
3848
3837
  return getColumnToFieldMap(contract, namespaceId, modelName)[columnName] ?? columnName;
3849
3838
  }
3839
+ function nullability(nullable) {
3840
+ return nullable ? "may be null" : "is never null";
3841
+ }
3842
+ function isFieldBuilder(value) {
3843
+ return "build" in value && typeof value.build === "function";
3844
+ }
3845
+ function isListMultiplicity(value) {
3846
+ return typeof value === "object" && value !== null && "elementNullable" in value && typeof value.elementNullable === "boolean";
3847
+ }
3848
+ function isMultiplicity(value) {
3849
+ return value === void 0 || value === false || isListMultiplicity(value);
3850
+ }
3851
+ function isFieldSpec(value) {
3852
+ return "codecId" in value && typeof value.codecId === "string" && "nullable" in value && typeof value.nullable === "boolean" && (!("many" in value) || isMultiplicity(value.many));
3853
+ }
3854
+ function multiplicity(many) {
3855
+ return isListMultiplicity(many) ? { elementNullable: many.elementNullable } : false;
3856
+ }
3857
+ const FIELD_DECLARATION_FIX = "Declare each field with a field builder, such as field.temporal.timestamptz().optional(), or with { codecId, nullable }. Declare a list with .many() or many: { elementNullable: false }, or, when its elements may be null, with .many({ elementsNullable: true }) or many: { elementNullable: true }.";
3858
+ function declaredFieldSpec(name, declaration) {
3859
+ if (typeof declaration === "object" && declaration !== null && isFieldBuilder(declaration)) {
3860
+ const built = declaration.build();
3861
+ const descriptor = typeof built === "object" && built !== null && "descriptor" in built ? built.descriptor : void 0;
3862
+ const nullable = typeof built === "object" && built !== null && "nullable" in built ? built.nullable : void 0;
3863
+ if (typeof descriptor !== "object" || descriptor === null || !("codecId" in descriptor) || typeof descriptor.codecId !== "string" || typeof nullable !== "boolean") throw ormError("ORM.ARGUMENT_INVALID", `Cannot define the scope: the field builder for ${name} names no column type`, {
3864
+ why: "A scope for any model matches each declared field by its codec and nullability, and this builder refers to a named type instead of a column type.",
3865
+ fix: "Declare the field with a builder that has a column type, such as field.text() or field.column(textColumn), or with { codecId, nullable }.",
3866
+ meta: { field: name }
3867
+ });
3868
+ const many = typeof built === "object" && built !== null && "many" in built && built.many;
3869
+ if (!isMultiplicity(many)) throw ormError("ORM.ARGUMENT_INVALID", `Cannot define the scope: the field builder for ${name} builds a many that is not false or { elementNullable }`, {
3870
+ why: `A field builder's build() returns many as false or undefined for one value, or as { elementNullable } with a boolean elementNullable for a list; received ${describeReceived(many)} for ${name}.`,
3871
+ fix: FIELD_DECLARATION_FIX,
3872
+ meta: { field: name }
3873
+ });
3874
+ return {
3875
+ codecId: descriptor.codecId,
3876
+ nullable,
3877
+ many: multiplicity(many)
3878
+ };
3879
+ }
3880
+ if (typeof declaration === "object" && declaration !== null && isFieldSpec(declaration)) return {
3881
+ codecId: declaration.codecId,
3882
+ nullable: declaration.nullable,
3883
+ many: multiplicity(declaration.many)
3884
+ };
3885
+ throw ormError("ORM.ARGUMENT_INVALID", `Cannot define the scope: the declaration of field ${name} is not a field builder or { codecId, nullable }`, {
3886
+ why: `Each field of a scope is declared with a field builder or with an object that has a string codecId, a boolean nullable and, for a list, many: { elementNullable } with a boolean elementNullable; received ${describeReceived(declaration)} for ${name}.`,
3887
+ fix: FIELD_DECLARATION_FIX,
3888
+ meta: { field: name }
3889
+ });
3890
+ }
3891
+ function declaredFieldSpecs(declarations) {
3892
+ if (typeof declarations !== "object" || declarations === null || Array.isArray(declarations)) throw ormError("ORM.ARGUMENT_INVALID", "Cannot define the scope: the fields are not an object", {
3893
+ why: `The first argument of scope maps the name of each field the scope needs to its declaration; received ${describeReceived(declarations)}.`,
3894
+ fix: FIELD_DECLARATION_FIX,
3895
+ meta: { argument: "fields" }
3896
+ });
3897
+ return Object.entries(declarations).map(([name, declaration]) => [name, declaredFieldSpec(name, declaration)]);
3898
+ }
3899
+ /** Throws `ORM.ARGUMENT_INVALID` unless `body`, the body of a scope, is a function. */
3900
+ function assertScopeBody(body) {
3901
+ if (typeof body !== "function") throw ormError("ORM.ARGUMENT_INVALID", "Cannot define the scope: the body is not a function", {
3902
+ why: `The body of a scope is a function that receives a collection and returns one; received ${describeReceived(body)}.`,
3903
+ fix: "Pass a function, such as (rows) => rows.where(...).",
3904
+ meta: { argument: "body" }
3905
+ });
3906
+ }
3907
+ function hasContract(ctx) {
3908
+ return "context" in ctx && typeof ctx.context === "object" && ctx.context !== null && "contract" in ctx.context && typeof ctx.context.contract === "object" && ctx.context.contract !== null;
3909
+ }
3910
+ function isModelCollection(value) {
3911
+ return typeof value === "object" && value !== null && "ctx" in value && typeof value.ctx === "object" && value.ctx !== null && hasContract(value.ctx) && "modelName" in value && typeof value.modelName === "string" && "namespaceId" in value && typeof value.namespaceId === "string";
3912
+ }
3913
+ /** Throws `ORM.ARGUMENT_INVALID` unless `value`, what a scope is applied to, is a collection. */
3914
+ function assertScopeReceiver(value) {
3915
+ if (!isModelCollection(value)) throw ormError("ORM.ARGUMENT_INVALID", "Cannot apply the scope: it was not given a collection", {
3916
+ why: `A scope is applied to a collection, such as db.orm.public.Post; received ${describeReceived(value)}.`,
3917
+ fix: "Run the scope with apply on a collection: collection.apply(scope).",
3918
+ meta: { argument: "collection" }
3919
+ });
3920
+ }
3921
+ /** Throws `ORM.ARGUMENT_INVALID` unless `value` is a collection of the model and namespace a scope for one model was made from. */
3922
+ function assertModelScopeReceiver(source, value) {
3923
+ assertScopeReceiver(value);
3924
+ if (value.modelName !== source.modelName || value.namespaceId !== source.namespaceId) {
3925
+ const made = `${source.namespaceId}.${source.modelName}`;
3926
+ const given = `${value.namespaceId}.${value.modelName}`;
3927
+ throw ormError("ORM.ARGUMENT_INVALID", `Cannot apply a scope for ${made} to a collection of ${given}`, {
3928
+ why: `The scope was made with ${made}.scope(...), and its body was written for that model.`,
3929
+ fix: `Apply the scope to a collection of ${made}, or make a scope from ${given}.`,
3930
+ meta: {
3931
+ model: source.modelName,
3932
+ namespace: source.namespaceId,
3933
+ receivedModel: value.modelName,
3934
+ receivedNamespace: value.namespaceId
3935
+ }
3936
+ });
3937
+ }
3938
+ }
3939
+ /** The model as error messages name it: with its namespace when the contract has more than one. */
3940
+ function modelLabel(collection) {
3941
+ return Object.keys(collection.ctx.context.contract.domain.namespaces).length > 1 ? `${collection.namespaceId}.${collection.modelName}` : collection.modelName;
3942
+ }
3943
+ /** Throws `ORM.ARGUMENT_INVALID` unless `result`, what a scope's body returned, is a collection of the receiver's model, namespace and class. */
3944
+ function assertScopeResult(receiver, result) {
3945
+ if (!(isModelCollection(result) && result.modelName === receiver.modelName && result.namespaceId === receiver.namespaceId && result instanceof receiver.constructor)) {
3946
+ const label = modelLabel(receiver);
3947
+ throw ormError("ORM.ARGUMENT_INVALID", `Cannot apply the scope to ${label}: its body did not return a collection of ${label}`, {
3948
+ why: `The body of a scope for any model returns the collection it received, after where, orderBy, limit or offset; it returned ${isModelCollection(result) ? `a collection of ${modelLabel(result)}` : describeReceived(result)}.`,
3949
+ fix: "Return the collection the body receives, or one made from it by calling its methods.",
3950
+ meta: {
3951
+ model: receiver.modelName,
3952
+ namespace: receiver.namespaceId,
3953
+ returned: isModelCollection(result) ? result.modelName : describeReceived(result)
3954
+ }
3955
+ });
3956
+ }
3957
+ }
3958
+ function elementNullability(elementNullable) {
3959
+ return elementNullable ? "may be null" : "are never null";
3960
+ }
3961
+ function sameMultiplicity(a, b) {
3962
+ return a === false || b === false ? a === b : a.elementNullable === b.elementNullable;
3963
+ }
3964
+ function fieldShape(many) {
3965
+ return many === false ? "holds one value" : `is a list whose elements ${elementNullability(many.elementNullable)}`;
3966
+ }
3967
+ function declarationFor(many) {
3968
+ if (many === false) return "as one value, without .many() or many";
3969
+ return many.elementNullable ? "as a list whose elements may be null, with .many({ elementsNullable: true }) or many: { elementNullable: true }" : "as a list whose elements are never null, with .many() or many: { elementNullable: false }";
3970
+ }
3971
+ function describeField(field) {
3972
+ const value = `with codec ${field.codecId} that ${nullability(field.nullable)}`;
3973
+ return field.many === false ? value : `${value} and whose elements ${elementNullability(field.many.elementNullable)}`;
3974
+ }
3975
+ function assertScopeFields(collection, fields) {
3976
+ const { contract } = collection.ctx.context;
3977
+ const { modelName, namespaceId } = collection;
3978
+ const label = modelLabel(collection);
3979
+ const model = modelOf(contract, namespaceId, modelName);
3980
+ for (const [name, spec] of fields) {
3981
+ const declared = `The scope was declared for models that have a ${spec.many === false ? "field" : "list field"} ${name} ${describeField(spec)}.`;
3982
+ const meta = {
3983
+ model: modelName,
3984
+ namespace: namespaceId,
3985
+ field: name,
3986
+ codecId: spec.codecId,
3987
+ nullable: spec.nullable,
3988
+ many: spec.many
3989
+ };
3990
+ const modelFields = model?.fields ?? {};
3991
+ if (!Object.hasOwn(modelFields, name)) throw ormError("ORM.FIELD_UNKNOWN", `Cannot apply a scope to ${label}: it has no field ${name}`, {
3992
+ why: declared,
3993
+ fix: `Apply the scope to a model that has a field ${name}, or remove ${name} from the declaration in the scope.`,
3994
+ meta
3995
+ });
3996
+ const fieldMany = multiplicity(modelFields[name]?.many);
3997
+ const column = resolveColumn(contract, namespaceId, collection.tableName, resolveFieldToColumn(contract, namespaceId, modelName, name));
3998
+ const actual = column === void 0 ? `${label}.${name} has no column.` : fieldMany === false ? `${label}.${name} has codec ${column.codecId} and ${nullability(column.nullable)}.` : `${label}.${name} is a list ${describeField({
3999
+ codecId: column.codecId,
4000
+ nullable: column.nullable,
4001
+ many: fieldMany
4002
+ })}.`;
4003
+ const sameCodecAndNullability = column?.codecId === spec.codecId && column.nullable === spec.nullable;
4004
+ if (!sameCodecAndNullability || !sameMultiplicity(fieldMany, spec.many)) throw ormError("ORM.FIELD_UNKNOWN", `Cannot apply a scope to ${label}: its field ${name} does not match the declaration`, {
4005
+ why: `${declared} ${actual}`,
4006
+ fix: sameCodecAndNullability ? `Apply the scope to a model whose ${name} field ${fieldShape(spec.many)}, or declare ${name} ${declarationFor(fieldMany)}.` : `Apply the scope to a model whose ${name} field has that codec and nullability, or change the declaration in the scope.`,
4007
+ meta
4008
+ });
4009
+ }
4010
+ }
4011
+ /**
4012
+ * Define a scope for any model that has the declared fields. Reached as the `scope` method of the client `orm()` returns.
4013
+ */
4014
+ function defineFieldScope(declarations, body) {
4015
+ const fields = declaredFieldSpecs(declarations);
4016
+ assertScopeBody(body);
4017
+ return blindCast((collection) => {
4018
+ const receiver = collection;
4019
+ assertScopeReceiver(receiver);
4020
+ assertScopeFields(receiver, fields);
4021
+ const result = body(blindCast(collection));
4022
+ assertScopeResult(receiver, result);
4023
+ return result;
4024
+ });
4025
+ }
4026
+ const SHOWN_LENGTH = 64;
4027
+ function shown(value) {
4028
+ const characters = Array.from(value);
4029
+ const cut = characters.length > SHOWN_LENGTH;
4030
+ return {
4031
+ text: JSON.stringify(cut ? `${characters.slice(0, SHOWN_LENGTH).join("")}…` : value),
4032
+ cut
4033
+ };
4034
+ }
4035
+ function describeReceived(value) {
4036
+ if (value === void 0 || value === null) return String(value);
4037
+ if (Array.isArray(value)) return "an array";
4038
+ const kind = typeof value;
4039
+ return kind === "object" ? "an object" : `a ${kind}`;
4040
+ }
4041
+ function cutNote(subject, value) {
4042
+ return value.cut ? ` The ${subject} above is cut to its first ${SHOWN_LENGTH} characters.` : "";
4043
+ }
4044
+ function fieldCodecId(collection, field) {
4045
+ const { contract } = collection.ctx.context;
4046
+ const column = resolveFieldToColumn(contract, collection.namespaceId, collection.modelName, field);
4047
+ return resolveColumn(contract, collection.namespaceId, collection.tableName, column)?.codecId;
4048
+ }
4049
+ function canOrder(collection, field) {
4050
+ const codecId = fieldCodecId(collection, field);
4051
+ return codecId !== void 0 && hasTrait(collection.ctx.context, codecId, "order");
4052
+ }
4053
+ function orderableFieldNames(collection) {
4054
+ const model = modelOf(collection.ctx.context.contract, collection.namespaceId, collection.modelName);
4055
+ return Object.keys(model?.fields ?? {}).filter((field) => canOrder(collection, field));
4056
+ }
4057
+ function whyNotOrderable(collection, name) {
4058
+ const { modelName } = collection;
4059
+ const model = modelOf(collection.ctx.context.contract, collection.namespaceId, modelName);
4060
+ const quoted = shown(name).text;
4061
+ if (Object.hasOwn(model?.relations ?? {}, name)) return `${quoted} is a relation of ${modelName}, not a field.`;
4062
+ if (!Object.hasOwn(model?.fields ?? {}, name)) return `${modelName} has no field ${quoted}.`;
4063
+ return canOrder(collection, name) ? `${quoted} is not one of the fields allowed for ordering.` : `The codec ${fieldCodecId(collection, name)} of ${modelName}.${name} cannot be ordered.`;
4064
+ }
4065
+ /**
4066
+ * An `orderBy` selector for a field named by a string, such as an order parameter of a request. `allowed` lists the fields a request may order by. A name that is not in `allowed` or not an orderable field of the collection's model, and a direction other than `asc` or `desc`, throw `ORM.ARGUMENT_INVALID`. An undefined direction is `asc`.
4067
+ *
4068
+ * ```ts
4069
+ * db.Post.orderBy(orderByField(db.Post, input.orderBy, input.direction, ['title', 'createdAt']));
4070
+ * ```
4071
+ */
4072
+ function orderByField(collection, name, direction, allowed) {
4073
+ const receiver = collection;
4074
+ if (!isModelCollection(receiver)) throw ormError("ORM.ARGUMENT_INVALID", "Cannot order: orderByField was not given a collection", {
4075
+ why: `orderByField takes the collection it orders, such as db.orm.public.Post; received ${describeReceived(receiver)}.`,
4076
+ fix: "Pass the collection the selector is for as the first argument.",
4077
+ meta: { argument: "collection" }
4078
+ });
4079
+ const { modelName } = collection;
4080
+ const requestedName = name;
4081
+ const requestedDirection = direction === void 0 ? "asc" : direction;
4082
+ const allowedList = allowed;
4083
+ if (!Array.isArray(allowedList) || allowedList.some((field) => typeof field !== "string")) throw ormError("ORM.ARGUMENT_INVALID", `Cannot order ${modelName}: the allowed fields are not a list of names`, {
4084
+ why: `orderByField takes the list of fields a request may order by; received ${describeReceived(allowedList)}.`,
4085
+ fix: `Pass an array of field names of ${modelName}, such as ['title', 'createdAt'].`,
4086
+ meta: {
4087
+ model: modelName,
4088
+ argument: "allowed"
4089
+ }
4090
+ });
4091
+ if (typeof requestedDirection !== "string") throw ormError("ORM.ARGUMENT_INVALID", `Cannot order ${modelName}: the direction is not a string`, {
4092
+ why: `An order direction is "asc" or "desc"; received ${describeReceived(requestedDirection)}.`,
4093
+ fix: "Pass \"asc\" or \"desc\".",
4094
+ meta: {
4095
+ model: modelName,
4096
+ direction: requestedDirection
4097
+ }
4098
+ });
4099
+ if (!isOrderByDirection(requestedDirection)) {
4100
+ const shownDirection = shown(requestedDirection);
4101
+ throw ormError("ORM.ARGUMENT_INVALID", `Cannot order ${modelName} in direction ${shownDirection.text}`, {
4102
+ why: "An order direction is \"asc\" or \"desc\".",
4103
+ fix: `Pass "asc" or "desc".${cutNote("direction", shownDirection)}`,
4104
+ meta: {
4105
+ model: modelName,
4106
+ direction: requestedDirection
4107
+ }
4108
+ });
4109
+ }
4110
+ const orderable = orderableFieldNames(collection);
4111
+ const names = allowedList.filter((field) => orderable.includes(field));
4112
+ const orderByOneOf = names.length === 0 ? `Pass an allowed list that names at least one field of ${modelName} that can be ordered.` : `Order by one of: ${names.join(", ")}.`;
4113
+ if (typeof requestedName !== "string") throw ormError("ORM.ARGUMENT_INVALID", `Cannot order ${modelName}: the field name is not a string`, {
4114
+ why: `An order field name is a string; received ${describeReceived(requestedName)}.`,
4115
+ fix: orderByOneOf,
4116
+ meta: {
4117
+ model: modelName,
4118
+ field: requestedName
4119
+ }
4120
+ });
4121
+ if (!names.includes(requestedName)) {
4122
+ const shownName = shown(requestedName);
4123
+ throw ormError("ORM.ARGUMENT_INVALID", `Cannot order ${modelName} by ${shownName.text}`, {
4124
+ why: whyNotOrderable(collection, requestedName),
4125
+ fix: `${orderByOneOf}${cutNote("name", shownName)}`,
4126
+ meta: {
4127
+ model: modelName,
4128
+ field: requestedName
4129
+ }
4130
+ });
4131
+ }
4132
+ const field = blindCast(requestedName);
4133
+ const order = requestedDirection;
4134
+ return (row) => row[field][order]();
4135
+ }
3850
4136
  function normalizeWhereArg(arg, options) {
3851
4137
  if (arg === void 0) return;
3852
4138
  if (arg === null) throw ormError("ORM.ARGUMENT_INVALID", "WhereArg cannot be null. Pass undefined or a valid WhereExpr/ToWhereExpr payload.", { meta: { argument: "where" } });
@@ -3857,6 +4143,99 @@ function normalizeWhereArg(arg, options) {
3857
4143
  function isToWhereExpr(arg) {
3858
4144
  return typeof arg === "object" && arg !== null && "toWhereExpr" in arg && !isWhereExpr(arg);
3859
4145
  }
4146
+ const CHAIN_PARTS = {
4147
+ orderBy: {
4148
+ noun: "an order",
4149
+ call: "orderBy()"
4150
+ },
4151
+ limit: {
4152
+ noun: "a limit",
4153
+ call: "limit()"
4154
+ },
4155
+ offset: {
4156
+ noun: "an offset",
4157
+ call: "offset()"
4158
+ },
4159
+ cursor: {
4160
+ noun: "a cursor",
4161
+ call: "cursor()"
4162
+ },
4163
+ distinct: {
4164
+ noun: "a distinct selection",
4165
+ call: "distinct()"
4166
+ },
4167
+ distinctOn: {
4168
+ noun: "a distinctOn selection",
4169
+ call: "distinctOn()"
4170
+ }
4171
+ };
4172
+ function presentParts(state, names) {
4173
+ const present = names.filter((name) => {
4174
+ const value = state[name];
4175
+ return Array.isArray(value) ? value.length > 0 : value !== void 0;
4176
+ });
4177
+ return {
4178
+ nouns: present.map((name) => CHAIN_PARTS[name].noun),
4179
+ calls: present.map((name) => CHAIN_PARTS[name].call)
4180
+ };
4181
+ }
4182
+ function listed(items, conjunction) {
4183
+ const last = items.at(-1) ?? "";
4184
+ return items.length > 1 ? `${items.slice(0, -1).join(", ")} ${conjunction} ${last}` : last;
4185
+ }
4186
+ const HIDDEN_BY_A_SCOPE = "A scope applied with apply can add one without showing it at the call site.";
4187
+ /** Throws `ORM.ARGUMENT_INVALID` when the collection has a limit, an offset, a cursor or a distinct selection, which `method`, a write of every matching row, would ignore. */
4188
+ function assertBulkWriteIgnoresNothing(state, modelName, method) {
4189
+ const { nouns, calls } = presentParts(state, [
4190
+ "limit",
4191
+ "offset",
4192
+ "cursor",
4193
+ "distinct",
4194
+ "distinctOn"
4195
+ ]);
4196
+ if (nouns.length === 0) return;
4197
+ const { limit, offset, cursor, distinct, distinctOn } = state;
4198
+ throw ormError("ORM.ARGUMENT_INVALID", `Cannot ${method} ${modelName}: the collection has ${listed(nouns, "and")}`, {
4199
+ why: `${method} changes every row that matches the filter. The statement it runs cannot apply ${listed(nouns, "or")}, so it would change more rows than the chain asks for. ${HIDDEN_BY_A_SCOPE}`,
4200
+ fix: `Remove ${listed(calls, "and")} before ${method}, or read the rows first and change them by their ids.`,
4201
+ meta: {
4202
+ model: modelName,
4203
+ method,
4204
+ limit,
4205
+ offset,
4206
+ cursor,
4207
+ distinct,
4208
+ distinctOn
4209
+ }
4210
+ });
4211
+ }
4212
+ /** Throws `ORM.ARGUMENT_INVALID` when the collection has an order, a limit, an offset, a cursor or a distinct selection, which an update with a relation callback would ignore. */
4213
+ function assertRelationUpdateIgnoresNothing(state, modelName) {
4214
+ const { nouns, calls } = presentParts(state, [
4215
+ "orderBy",
4216
+ "limit",
4217
+ "offset",
4218
+ "cursor",
4219
+ "distinct",
4220
+ "distinctOn"
4221
+ ]);
4222
+ if (nouns.length === 0) return;
4223
+ const { orderBy, limit, offset, cursor, distinct, distinctOn } = state;
4224
+ throw ormError("ORM.ARGUMENT_INVALID", `Cannot update ${modelName} with a relation mutation: the collection has ${listed(nouns, "and")}`, {
4225
+ why: `An update that changes a relation finds its row by the filter alone. It would ignore ${listed(nouns, "and")}, and could change another row than first() returns. ${HIDDEN_BY_A_SCOPE}`,
4226
+ fix: `Remove ${listed(calls, "and")} before update, or filter to the one row, such as by its id.`,
4227
+ meta: {
4228
+ model: modelName,
4229
+ method: "update",
4230
+ ordered: orderBy !== void 0 && orderBy.length > 0,
4231
+ limit,
4232
+ offset,
4233
+ cursor,
4234
+ distinct,
4235
+ distinctOn
4236
+ }
4237
+ });
4238
+ }
3860
4239
  function applyCreateDefaults(ctx, namespaceId, tableName, rows, defaultValueCache = /* @__PURE__ */ new Map()) {
3861
4240
  for (const row of rows) {
3862
4241
  const applied = ctx.context.applyMutationDefaults({
@@ -3975,25 +4354,57 @@ var CollectionBase = class CollectionBase {
3975
4354
  if (!filter) return blindCast(this);
3976
4355
  return this.#cloneSelf({ filters: [...this.state.filters, filter] });
3977
4356
  }
3978
- /**
3979
- * Call `fn` with this collection and return its result.
3980
- */
3981
4357
  apply(fn) {
3982
4358
  return fn(this);
3983
4359
  }
3984
- variant(variantName) {
3985
- const model = modelOf(this.contract, this.namespaceId, this.modelName);
3986
- const discriminator = model?.discriminator;
3987
- const variants = model?.variants;
3988
- if (!discriminator || !variants) return blindCast(this);
3989
- const variantEntry = variants[variantName];
3990
- if (!variantEntry) return blindCast(this);
3991
- const columnName = resolveFieldToColumn(this.contract, this.namespaceId, this.modelName, discriminator.field);
3992
- const filter = BinaryExpr.eq(ColumnRef.of(this.tableName, columnName), LiteralExpr.of(variantEntry.value));
3993
- const filtersWithoutPreviousVariant = this.state.variantName ? this.state.filters.filter((f) => !(f instanceof BinaryExpr && f.left instanceof ColumnRef && f.left.column === columnName && f.left.table === this.tableName)) : this.state.filters;
4360
+ /**
4361
+ * Define a scope for this collection's model, such as a shared `select` and `include`. The body is typed once, against the model's plain collection. The scope accepts any collection of the model that `select` and `variant` have not narrowed.
4362
+ *
4363
+ * ```ts
4364
+ * const summary = db.Post.scope((posts) => posts.select('id', 'title').include('user'));
4365
+ * db.User.include('posts', (posts) => posts.apply(summary));
4366
+ * ```
4367
+ */
4368
+ scope(body) {
4369
+ assertScopeBody(body);
4370
+ const source = {
4371
+ modelName: this.modelName,
4372
+ namespaceId: this.namespaceId
4373
+ };
4374
+ return (collection) => {
4375
+ assertModelScopeReceiver(source, collection);
4376
+ return body(blindCast(collection));
4377
+ };
4378
+ }
4379
+ variant(value) {
4380
+ const polyInfo = resolvePolymorphismInfo(this.contract, this.namespaceId, this.modelName);
4381
+ const selectedVariantName = this.state.variantName;
4382
+ if (selectedVariantName !== void 0) {
4383
+ const selectedValue = polyInfo?.variants.get(selectedVariantName)?.value;
4384
+ throw ormError("ORM.OPERATION_UNSUPPORTED", `variant("${value}") cannot be called on model "${this.modelName}" because variant("${selectedValue}") is already selected; call variant() on the base collection instead`, { meta: {
4385
+ method: "variant",
4386
+ model: this.modelName,
4387
+ variant: selectedVariantName,
4388
+ selectedValue,
4389
+ reason: "variant-already-selected"
4390
+ } });
4391
+ }
4392
+ const variantInfo = polyInfo?.variantsByValue.get(value);
4393
+ if (!polyInfo || !variantInfo) {
4394
+ const declaredValues = [...polyInfo?.variantsByValue.keys() ?? []];
4395
+ throw ormError("ORM.ARGUMENT_INVALID", declaredValues.length === 0 ? `variant("${value}") cannot narrow model "${this.modelName}": it declares no discriminator values` : `variant("${value}") cannot narrow model "${this.modelName}": the declared discriminator values are ${declaredValues.map((declared) => `"${declared}"`).join(", ")}`, { meta: {
4396
+ method: "variant",
4397
+ argument: "value",
4398
+ model: this.modelName,
4399
+ value,
4400
+ declaredValues
4401
+ } });
4402
+ }
4403
+ const columnName = polyInfo.discriminatorColumn;
4404
+ const filter = BinaryExpr.eq(ColumnRef.of(this.tableName, columnName), LiteralExpr.of(variantInfo.value));
3994
4405
  return this.#cloneWithRow({
3995
- filters: [...filtersWithoutPreviousVariant, filter],
3996
- variantName
4406
+ filters: [...this.state.filters, filter],
4407
+ variantName: variantInfo.modelName
3997
4408
  });
3998
4409
  }
3999
4410
  include(relationName, refineFn) {
@@ -4533,6 +4944,7 @@ var CollectionBase = class CollectionBase {
4533
4944
  assertReturningCapability(this.contract, "update()");
4534
4945
  const annotationsMap = this.#collectAnnotationsFromMeta(configure, "write", "update");
4535
4946
  if (hasNestedMutationCallbacks(this.contract, this.namespaceId, this.modelName, blindCast(data))) {
4947
+ assertRelationUpdateIgnoresNothing(this.state, this.modelName);
4536
4948
  const updatedRow = await executeNestedUpdateMutation({
4537
4949
  context: this.ctx.context,
4538
4950
  runtime: this.ctx.runtime,
@@ -4553,6 +4965,7 @@ var CollectionBase = class CollectionBase {
4553
4965
  });
4554
4966
  }
4555
4967
  updateAll(data, configure) {
4968
+ assertBulkWriteIgnoresNothing(this.state, this.modelName, "updateAll");
4556
4969
  return this.#updateAllWithAnnotations(data, this.#collectAnnotationsFromMeta(configure, "write", "updateAll"));
4557
4970
  }
4558
4971
  #updateAllWithAnnotations(data, annotationsMap) {
@@ -4580,6 +4993,7 @@ var CollectionBase = class CollectionBase {
4580
4993
  });
4581
4994
  }
4582
4995
  async updateAndCount(data, configure) {
4996
+ assertBulkWriteIgnoresNothing(this.state, this.modelName, "updateAndCount");
4583
4997
  const mappedData = mapModelDataToStorageRow(this.contract, this.namespaceId, this.modelName, data);
4584
4998
  if (Object.keys(mappedData).length === 0) return 0;
4585
4999
  applyUpdateDefaults(this.ctx, this.namespaceId, this.tableName, mappedData);
@@ -4594,10 +5008,15 @@ var CollectionBase = class CollectionBase {
4594
5008
  const scoped = this.#withRuntime(scope);
4595
5009
  const identityWhere = await scoped.#findFirstMatchingRowIdentityWhere();
4596
5010
  if (!identityWhere) return null;
4597
- return (await scoped.#clone({ filters: [identityWhere] }).#executeDeleteReturning(annotationsMap).toArray())[0] ?? null;
5011
+ return (await scoped.#clone({
5012
+ filters: [identityWhere],
5013
+ limit: void 0,
5014
+ offset: void 0
5015
+ }).#executeDeleteReturning(annotationsMap).toArray())[0] ?? null;
4598
5016
  });
4599
5017
  }
4600
5018
  deleteAll(configure) {
5019
+ assertBulkWriteIgnoresNothing(this.state, this.modelName, "deleteAll");
4601
5020
  return this.#deleteAllWithAnnotations(this.#collectAnnotationsFromMeta(configure, "write", "deleteAll"));
4602
5021
  }
4603
5022
  #deleteAllWithAnnotations(annotationsMap) {
@@ -4656,6 +5075,7 @@ var CollectionBase = class CollectionBase {
4656
5075
  return new AsyncIterableResult(generator());
4657
5076
  }
4658
5077
  async deleteAndCount(configure) {
5078
+ assertBulkWriteIgnoresNothing(this.state, this.modelName, "deleteAndCount");
4659
5079
  const annotationsMap = this.#collectAnnotationsFromMeta(configure, "write", "deleteAndCount");
4660
5080
  const compiled = mergeAnnotations(compileDeleteCount(this.contract, this.namespaceId, this.tableName, this.state.filters, this.state.variantName, this.modelName), annotationsMap);
4661
5081
  return (await this.ctx.runtime.execute(compiled)).affectedRows;
@@ -4707,6 +5127,8 @@ var CollectionBase = class CollectionBase {
4707
5127
  model: this.modelName,
4708
5128
  table: this.tableName
4709
5129
  } });
5130
+ checkLimitOffset("limit", this.state.limit);
5131
+ if (this.state.limit === 0) return null;
4710
5132
  const firstRow = await this.#clone({
4711
5133
  selectedFields: [...identityColumns],
4712
5134
  includes: []
@@ -4920,8 +5342,8 @@ function orm(options) {
4920
5342
  }
4921
5343
  return new Proxy({}, { get(_target, prop) {
4922
5344
  if (typeof prop !== "string") return;
4923
- if (!Object.hasOwn(contract.domain.namespaces, prop)) return;
4924
- return namespaceFacet(prop);
5345
+ if (Object.hasOwn(contract.domain.namespaces, prop)) return namespaceFacet(prop);
5346
+ return prop === "scope" ? defineFieldScope : void 0;
4925
5347
  } });
4926
5348
  }
4927
5349
  function createCollectionRegistry(contract, collections) {
@@ -4968,6 +5390,6 @@ function createPreparedRowQuery(description, statement) {
4968
5390
  } });
4969
5391
  }
4970
5392
  //#endregion
4971
- export { Collection, GroupedCollection, all, and, createModelAccessor, createPreparedRowQuery, emptyState, not, or, orm, prepareQuery };
5393
+ export { Collection, GroupedCollection, all, and, createModelAccessor, createPreparedRowQuery, emptyState, not, or, orderByField, orm, prepareQuery };
4972
5394
 
4973
5395
  //# sourceMappingURL=orm-client.mjs.map