arkormx 2.10.2 → 2.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_relationship = require('./relationship-DWtfgLfh.cjs');
2
+ const require_relationship = require('./relationship-IC-TAFyG.cjs');
3
3
  let pg = require("pg");
4
4
  let node_path = require("node:path");
5
5
  let module$1 = require("module");
@@ -65,7 +65,8 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
65
65
  rawWhere: true,
66
66
  distinct: true,
67
67
  groupBy: true,
68
- joins: true
68
+ joins: true,
69
+ expressions: true
69
70
  };
70
71
  }
71
72
  resolveConfiguredDatabaseName(connectionString) {
@@ -386,6 +387,13 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
386
387
  }
387
388
  buildSchemaColumnDefinition(table, column) {
388
389
  const parts = [this.quoteIdentifier(column.map ?? column.name), this.resolveSchemaColumnType(table, column)];
390
+ if (column.generatedExpression) {
391
+ const storage = column.generatedStored === false ? "" : " stored";
392
+ parts.push(`generated always as (${column.generatedExpression})${storage}`);
393
+ if (column.unique) parts.push("unique");
394
+ if (!column.nullable && !column.primary) parts.push("not null");
395
+ return parts.join(" ");
396
+ }
389
397
  if (this.shouldUseIdentity(column)) parts.push("generated by default as identity");
390
398
  const defaultValue = this.resolveSchemaColumnDefault(column);
391
399
  if (defaultValue && !this.shouldUseIdentity(column)) parts.push(`default ${defaultValue}`);
@@ -643,11 +651,16 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
643
651
  }
644
652
  buildSelectList(target, columns) {
645
653
  if (!columns || columns.length === 0) return kysely.sql.raw("*");
646
- return kysely.sql.join(columns.map(({ column, alias, raw, wildcard }) => {
654
+ return kysely.sql.join(columns.map(({ column, alias, raw, wildcard, expression }) => {
647
655
  if (wildcard) return kysely.sql.raw("*");
656
+ if (expression) {
657
+ const compiled = this.buildExpression(target, expression);
658
+ const resultAlias = alias ?? column;
659
+ return resultAlias ? kysely.sql`${compiled} as ${kysely.sql.id(resultAlias)}` : compiled;
660
+ }
648
661
  if (raw) {
649
- const expression = kysely.sql.raw(column);
650
- return alias ? kysely.sql`${expression} as ${kysely.sql.id(alias)}` : expression;
662
+ const rawExpression = kysely.sql.raw(column);
663
+ return alias ? kysely.sql`${rawExpression} as ${kysely.sql.id(alias)}` : rawExpression;
651
664
  }
652
665
  const mappedColumn = this.mapColumn(target, column);
653
666
  const resultAlias = alias ?? column;
@@ -657,13 +670,18 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
657
670
  }
658
671
  buildOrderBy(target, orderBy) {
659
672
  if (!orderBy || orderBy.length === 0) return kysely.sql``;
660
- return kysely.sql` order by ${kysely.sql.join(orderBy.map(({ column, direction }) => {
661
- return kysely.sql`${kysely.sql.ref(this.mapColumn(target, column))} ${kysely.sql.raw(direction === "desc" ? "desc" : "asc")}`;
673
+ return kysely.sql` order by ${kysely.sql.join(orderBy.map(({ column, direction, expression }) => {
674
+ return kysely.sql`${expression ? this.buildExpression(target, expression) : kysely.sql.ref(this.mapColumn(target, column))} ${kysely.sql.raw(direction === "desc" ? "desc" : "asc")}`;
662
675
  }), kysely.sql`, `)}`;
663
676
  }
664
677
  buildGroupBy(target, groupBy) {
665
678
  if (!groupBy || groupBy.length === 0) return kysely.sql``;
666
- return kysely.sql` group by ${kysely.sql.join(groupBy.map((column) => kysely.sql.ref(this.mapColumn(target, column))), kysely.sql`, `)}`;
679
+ return kysely.sql` group by ${kysely.sql.join(groupBy.map((item) => {
680
+ if (typeof item === "string") return kysely.sql.ref(this.mapColumn(target, item));
681
+ if ("alias" in item) return kysely.sql.ref(item.alias);
682
+ if ("expression" in item) return this.buildExpression(target, item.expression);
683
+ return this.buildRawExpressionFragment(item.raw.sql, item.raw.bindings ?? []);
684
+ }), kysely.sql`, `)}`;
667
685
  }
668
686
  buildHavingClause(target, having) {
669
687
  if (!having) return kysely.sql``;
@@ -812,6 +830,96 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
812
830
  const contains = kysely.sql`${accessor} @> ${jsonValue}::jsonb`;
813
831
  return condition.not ? kysely.sql`not (${contains})` : contains;
814
832
  }
833
+ /**
834
+ * Compiles a serialized {@link ExpressionNode} into a parameterized SQL fragment.
835
+ * Shared by expression-backed select columns, `group by`, `order by`, and any
836
+ * boolean expression used as a `where`/`having` predicate.
837
+ *
838
+ * @param target
839
+ * @param node
840
+ * @returns
841
+ */
842
+ buildExpression(target, node) {
843
+ switch (node.kind) {
844
+ case "column": return this.buildExpressionColumn(target, node.name);
845
+ case "value": return kysely.sql`${node.value}`;
846
+ case "raw": return this.buildRawExpressionFragment(node.sql, node.bindings);
847
+ case "json": return this.buildJsonValueExpression(target, node);
848
+ case "function": {
849
+ const args = node.args.map((arg) => this.buildExpression(target, arg));
850
+ return kysely.sql`${kysely.sql.raw(this.sanitizeFunctionName(node.name))}(${kysely.sql.join(args, kysely.sql`, `)})`;
851
+ }
852
+ case "case": {
853
+ const branches = node.cases.map((branch) => kysely.sql`when ${this.buildExpression(target, branch.when)} then ${this.buildExpression(target, branch.then)}`);
854
+ const elseClause = node.else ? kysely.sql` else ${this.buildExpression(target, node.else)}` : kysely.sql``;
855
+ return kysely.sql`case ${kysely.sql.join(branches, kysely.sql` `)}${elseClause} end`;
856
+ }
857
+ case "binary": return this.buildBinaryExpression(target, node);
858
+ case "in": {
859
+ const operand = this.buildExpression(target, node.operand);
860
+ const values = node.values.map((value) => this.buildExpression(target, value));
861
+ const list = values.length > 0 ? kysely.sql.join(values, kysely.sql`, `) : kysely.sql`null`;
862
+ return node.not ? kysely.sql`(${operand} not in (${list}))` : kysely.sql`(${operand} in (${list}))`;
863
+ }
864
+ case "null-check": {
865
+ const operand = this.buildExpression(target, node.operand);
866
+ return node.not ? kysely.sql`(${operand} is not null)` : kysely.sql`(${operand} is null)`;
867
+ }
868
+ case "aggregate": return this.buildAggregateExpression(target, node);
869
+ default: throw new require_relationship.ArkormException(`Unsupported expression node [${node.kind}].`);
870
+ }
871
+ }
872
+ buildExpressionColumn(target, name) {
873
+ if (name.includes(".")) return kysely.sql.ref(name);
874
+ return kysely.sql.ref(this.mapColumn(target, name));
875
+ }
876
+ buildBinaryExpression(target, node) {
877
+ const left = this.buildExpression(target, node.left);
878
+ const right = this.buildExpression(target, node.right);
879
+ switch (node.operator) {
880
+ case "like": return kysely.sql`(${left} like ${right})`;
881
+ case "ilike": return kysely.sql`(${left} ilike ${right})`;
882
+ case "not-like": return kysely.sql`(${left} not like ${right})`;
883
+ case "not-ilike": return kysely.sql`(${left} not ilike ${right})`;
884
+ case "and": return kysely.sql`(${left} and ${right})`;
885
+ case "or": return kysely.sql`(${left} or ${right})`;
886
+ default: return kysely.sql`(${left} ${kysely.sql.raw(node.operator)} ${right})`;
887
+ }
888
+ }
889
+ buildAggregateExpression(target, node) {
890
+ const argument = node.arg ? this.buildExpression(target, node.arg) : kysely.sql.raw("*");
891
+ const distinctKeyword = node.distinct ? kysely.sql`distinct ` : kysely.sql``;
892
+ let call = kysely.sql`${kysely.sql.raw(node.fn)}(${distinctKeyword}${argument})`;
893
+ if (node.filter) call = kysely.sql`${call} filter (where ${this.buildExpression(target, node.filter)})`;
894
+ if (node.fn === "sum" || node.fn === "avg") return kysely.sql`(${call})::double precision`;
895
+ if (node.fn === "count") return kysely.sql`(${call})::bigint`;
896
+ return call;
897
+ }
898
+ buildJsonValueExpression(target, node) {
899
+ const base = kysely.sql`${kysely.sql.ref(this.mapColumn(target, node.column))}::jsonb`;
900
+ let accessor;
901
+ if (node.path.length === 0) accessor = base;
902
+ else if (node.path.length === 1) accessor = kysely.sql`(${base} ->> ${node.path[0]})`;
903
+ else accessor = kysely.sql`(${base} #>> ${`{${node.path.join(",")}}`}::text[])`;
904
+ if (node.cast === "number") return kysely.sql`(${accessor})::numeric`;
905
+ if (node.cast === "boolean") return kysely.sql`(${accessor})::boolean`;
906
+ return accessor;
907
+ }
908
+ buildRawExpressionFragment(rawSql, bindings) {
909
+ const segments = rawSql.split("?");
910
+ if (segments.length !== bindings.length + 1) throw new require_relationship.ArkormException("Raw expression bindings do not match the number of placeholders.");
911
+ const parts = [];
912
+ segments.forEach((segment, index) => {
913
+ if (segment.length > 0) parts.push(kysely.sql.raw(this.quoteCamelCaseIdentifiers(segment)));
914
+ if (index < bindings.length) parts.push(kysely.sql`${bindings[index]}`);
915
+ });
916
+ if (parts.length === 0) return kysely.sql``;
917
+ return kysely.sql`${kysely.sql.join(parts, kysely.sql``)}`;
918
+ }
919
+ sanitizeFunctionName(name) {
920
+ if (!/^[a-zA-Z_][a-zA-Z0-9_.]*$/.test(name)) throw new require_relationship.ArkormException(`Unsupported SQL function name [${name}].`);
921
+ return name;
922
+ }
815
923
  buildWhereCondition(target, condition) {
816
924
  if (!condition) return kysely.sql`1 = 1`;
817
925
  if (condition.type === "comparison") return this.buildComparisonCondition(target, condition);
@@ -821,6 +929,7 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
821
929
  if (condition.type === "exists") return this.buildExistsCondition(condition);
822
930
  if (condition.type === "full-text") return this.buildFullTextCondition(target, condition);
823
931
  if (condition.type === "json") return this.buildJsonCondition(target, condition);
932
+ if (condition.type === "expression") return kysely.sql`${this.buildExpression(target, condition.expression)}`;
824
933
  if (condition.type === "group") {
825
934
  const group = condition;
826
935
  const conditions = group.conditions.map((entry) => {
@@ -1693,6 +1802,7 @@ var PrismaDatabaseAdapter = class PrismaDatabaseAdapter {
1693
1802
  rawWhere: false,
1694
1803
  distinct: false,
1695
1804
  groupBy: false,
1805
+ expressions: false,
1696
1806
  returning: false
1697
1807
  };
1698
1808
  }
@@ -1728,6 +1838,14 @@ var PrismaDatabaseAdapter = class PrismaDatabaseAdapter {
1728
1838
  }
1729
1839
  toQuerySelect(columns) {
1730
1840
  if (!columns || columns.length === 0) return void 0;
1841
+ const expressionColumn = columns.find((column) => column.expression);
1842
+ if (expressionColumn) throw new require_relationship.UnsupportedAdapterFeatureException("Expression select columns are not supported by the Prisma compatibility adapter; use a SQL-backed adapter.", {
1843
+ operation: "adapter.select",
1844
+ meta: {
1845
+ feature: "expressions",
1846
+ alias: expressionColumn.alias
1847
+ }
1848
+ });
1731
1849
  const rawColumn = columns.find((column) => column.raw);
1732
1850
  if (rawColumn) throw new require_relationship.UnsupportedAdapterFeatureException("Raw select expressions are not supported by the Prisma compatibility adapter; use a SQL-backed adapter or DB.raw().", {
1733
1851
  operation: "adapter.select",
@@ -1745,6 +1863,10 @@ var PrismaDatabaseAdapter = class PrismaDatabaseAdapter {
1745
1863
  }
1746
1864
  toQueryOrderBy(orderBy) {
1747
1865
  if (!orderBy || orderBy.length === 0) return void 0;
1866
+ if (orderBy.some((entry) => entry.expression)) throw new require_relationship.UnsupportedAdapterFeatureException("Order-by expressions are not supported by the Prisma compatibility adapter; use a SQL-backed adapter.", {
1867
+ operation: "adapter.select",
1868
+ meta: { feature: "expressions" }
1869
+ });
1748
1870
  return orderBy.map((entry) => ({ [entry.column]: entry.direction }));
1749
1871
  }
1750
1872
  toComparisonWhere(condition) {
@@ -3388,7 +3510,8 @@ var Migration = class {
3388
3510
  //#region src/cli/commands/MigrateCommand.ts
3389
3511
  /**
3390
3512
  * The MigrateCommand class implements the CLI command for applying migration
3391
- * classes to the Prisma schema and running the Prisma workflow.
3513
+ * classes to the database or Prisma schema and running the Prisma workflow when
3514
+ * using the Prisma compatibility driver.
3392
3515
  *
3393
3516
  * @author Legacy (3m1n3nc3)
3394
3517
  * @since 0.1.0
@@ -3399,22 +3522,22 @@ var MigrateCommand = class extends _h3ravel_musket.Command {
3399
3522
  this.signature = `migrate
3400
3523
  {name? : Migration class or file name}
3401
3524
  {--all : Run all migrations from the configured migrations directory}
3402
- {--deploy : Use prisma migrate deploy instead of migrate dev}
3403
- {--skip-generate : Skip prisma generate}
3525
+ {--deploy : Use prisma migrate deploy instead of migrate dev (Prisma compatibility driver only)}
3526
+ {--skip-generate : Skip prisma generate (Prisma compatibility driver only)}
3404
3527
  {--skip-migrate : Skip prisma migrate command}
3405
3528
  {--state-file= : Path to applied migration state file}
3406
- {--schema= : Explicit prisma schema path}
3407
- {--migration-name= : Name for prisma migrate dev}
3529
+ {--schema= : Explicit prisma schema path (Prisma compatibility driver only)}
3530
+ {--migration-name= : Name for prisma migrate dev (Prisma compatibility driver only)}
3408
3531
  {--create-database : Create the configured database without prompting}
3409
3532
  `;
3410
- this.description = "Apply migration classes to schema.prisma and run Prisma workflow";
3533
+ this.description = "Apply migration classes to the database or schema.prisma and run Prisma workflow when using the Prisma compatibility driver";
3411
3534
  }
3412
3535
  /**
3413
3536
  * Command handler for the migrate command.
3414
3537
  * This method is responsible for orchestrating the migration
3415
3538
  * process, including loading migration classes, applying them to
3416
- * the Prisma schema, and running the appropriate Prisma commands
3417
- * based on the provided options.
3539
+ * the the database or Prisma schema, and running the appropriate Prisma commands
3540
+ * when using the Prisma compatibility driver based on the provided options.
3418
3541
  *
3419
3542
  * @returns
3420
3543
  */
@@ -3623,10 +3746,10 @@ var MigrateFreshCommand = class extends _h3ravel_musket.Command {
3623
3746
  constructor(..._args) {
3624
3747
  super(..._args);
3625
3748
  this.signature = `migrate:fresh
3626
- {--skip-generate : Skip prisma generate}
3627
- {--skip-migrate : Skip prisma database sync}
3749
+ {--skip-generate : Skip prisma generate (Prisma compatibility driver only)}
3750
+ {--skip-migrate : Skip prisma database sync (Prisma compatibility driver only)}
3628
3751
  {--state-file= : Path to applied migration state file}
3629
- {--schema= : Explicit prisma schema path}
3752
+ {--schema= : Explicit prisma schema path (Prisma compatibility driver only)}
3630
3753
  {--create-database : Create the configured database without prompting}
3631
3754
  `;
3632
3755
  this.description = "Reset the database and rerun all migration classes";
@@ -3781,12 +3904,12 @@ var MigrateRollbackCommand = class extends _h3ravel_musket.Command {
3781
3904
  this.signature = `migrate:rollback
3782
3905
  {--step= : Number of latest applied migration classes to rollback}
3783
3906
  {--dry-run : Preview rollback targets without applying changes}
3784
- {--deploy : Use prisma migrate deploy instead of migrate dev}
3785
- {--skip-generate : Skip prisma generate}
3786
- {--skip-migrate : Skip prisma migrate command}
3907
+ {--deploy : Use prisma migrate deploy instead of migrate dev (Prisma compatibility driver only)}
3908
+ {--skip-generate : Skip prisma generate (Prisma compatibility driver only)}
3909
+ {--skip-migrate : Skip prisma migrate command (Prisma compatibility driver only)}
3787
3910
  {--state-file= : Path to applied migration state file}
3788
- {--schema= : Explicit prisma schema path}
3789
- {--migration-name= : Name for prisma migrate dev}
3911
+ {--schema= : Explicit prisma schema path (Prisma compatibility driver only)}
3912
+ {--migration-name= : Name for prisma migrate dev (Prisma compatibility driver only)}
3790
3913
  `;
3791
3914
  this.description = "Rollback migration classes from schema.prisma and run Prisma workflow";
3792
3915
  }
@@ -3801,7 +3924,7 @@ var MigrateRollbackCommand = class extends _h3ravel_musket.Command {
3801
3924
  const useDatabaseMigrations = require_relationship.supportsDatabaseMigrationExecution(adapter);
3802
3925
  const persistedFeatures = require_relationship.resolvePersistedMetadataFeatures(this.app.getConfig("features"));
3803
3926
  let appliedState = await require_relationship.readAppliedMigrationsStateFromStore(adapter, stateFilePath);
3804
- const stepOption = this.option("step");
3927
+ const stepOption = this.option("step", 1);
3805
3928
  const stepCount = stepOption == null ? void 0 : Number(stepOption);
3806
3929
  if (stepCount != null && (!Number.isFinite(stepCount) || stepCount <= 0 || !Number.isInteger(stepCount))) return void this.error("Error: --step must be a positive integer.");
3807
3930
  const targets = stepCount ? require_relationship.getLatestAppliedMigrations(appliedState, stepCount) : (() => {
@@ -4476,14 +4599,34 @@ var QueryBuilder = class QueryBuilder {
4476
4599
  return Math.max(1, resolvedPage);
4477
4600
  }
4478
4601
  where(whereOrCallback) {
4602
+ if (whereOrCallback instanceof require_relationship.Expression) return this.appendExpressionCondition("AND", whereOrCallback);
4479
4603
  if (typeof whereOrCallback === "function") return this.appendNestedWhere("AND", whereOrCallback);
4480
4604
  return this.addLogicalWhere("AND", whereOrCallback);
4481
4605
  }
4482
4606
  orWhere(whereOrCallback) {
4607
+ if (whereOrCallback instanceof require_relationship.Expression) return this.appendExpressionCondition("OR", whereOrCallback);
4483
4608
  if (typeof whereOrCallback === "function") return this.appendNestedWhere("OR", whereOrCallback);
4484
4609
  return this.addLogicalWhere("OR", whereOrCallback);
4485
4610
  }
4486
4611
  /**
4612
+ * Appends a boolean {@link Expression} as a where predicate. When the query is
4613
+ * using the Prisma-like legacy where representation, the expression is merged in
4614
+ * as a structured condition alongside it.
4615
+ */
4616
+ appendExpressionCondition(boolean, expression) {
4617
+ const condition = {
4618
+ type: "expression",
4619
+ expression: expression.toExpressionNode()
4620
+ };
4621
+ if (this.legacyWhere) {
4622
+ const existing = this.tryBuildQueryCondition(this.legacyWhere);
4623
+ this.legacyWhere = void 0;
4624
+ if (existing) this.queryWhere = existing;
4625
+ }
4626
+ this.appendQueryCondition(boolean, condition);
4627
+ return this;
4628
+ }
4629
+ /**
4487
4630
  * Resolve a callback into a parenthesized group condition and append it.
4488
4631
  */
4489
4632
  appendNestedWhere(boolean, callback) {
@@ -5133,15 +5276,17 @@ var QueryBuilder = class QueryBuilder {
5133
5276
  whereIn(key, values) {
5134
5277
  return this.where({ [key]: { in: values } });
5135
5278
  }
5136
- /**
5137
- * Adds an orderBy clause to the query. This will overwrite any existing orderBy clause.
5138
- *
5139
- * @param orderBy
5140
- * @returns
5141
- */
5142
- orderBy(orderBy) {
5279
+ orderBy(orderByOrExpression, direction = "asc") {
5143
5280
  this.randomOrderEnabled = false;
5144
- const normalized = this.normalizeQueryOrderBy(orderBy);
5281
+ if (orderByOrExpression instanceof require_relationship.Expression) {
5282
+ this.queryOrderBy = [...this.queryOrderBy ?? [], {
5283
+ column: "",
5284
+ direction,
5285
+ expression: orderByOrExpression.toExpressionNode()
5286
+ }];
5287
+ return this;
5288
+ }
5289
+ const normalized = this.normalizeQueryOrderBy(orderByOrExpression);
5145
5290
  if (!normalized) throw new require_relationship.UnsupportedAdapterFeatureException("Order clauses must use Arkorm-normalizable column directions.", {
5146
5291
  operation: "orderBy",
5147
5292
  model: this.model.name
@@ -5150,6 +5295,28 @@ var QueryBuilder = class QueryBuilder {
5150
5295
  return this;
5151
5296
  }
5152
5297
  /**
5298
+ * Appends a raw SQL `order by` fragment (with positional `?` bindings), useful
5299
+ * for ordering by a computed expression the builder does not model directly.
5300
+ *
5301
+ * @param sql
5302
+ * @param bindings
5303
+ * @param direction
5304
+ * @returns
5305
+ */
5306
+ orderByRaw(sql, bindings = [], direction = "asc") {
5307
+ this.randomOrderEnabled = false;
5308
+ this.queryOrderBy = [...this.queryOrderBy ?? [], {
5309
+ column: "",
5310
+ direction,
5311
+ expression: {
5312
+ kind: "raw",
5313
+ sql,
5314
+ bindings
5315
+ }
5316
+ }];
5317
+ return this;
5318
+ }
5319
+ /**
5153
5320
  * Puts the query results in random order.
5154
5321
  *
5155
5322
  * @returns
@@ -5515,12 +5682,6 @@ var QueryBuilder = class QueryBuilder {
5515
5682
  pipe(callback) {
5516
5683
  return callback(this);
5517
5684
  }
5518
- /**
5519
- * Adds a select clause to the query. This will overwrite any existing select clause.
5520
- *
5521
- * @param select
5522
- * @returns
5523
- */
5524
5685
  select(select) {
5525
5686
  const normalized = this.normalizeQuerySelect(select);
5526
5687
  if (normalized === null) throw new require_relationship.UnsupportedAdapterFeatureException("Select clauses must use Arkorm-normalizable column projections.", {
@@ -5530,12 +5691,6 @@ var QueryBuilder = class QueryBuilder {
5530
5691
  this.querySelect = normalized;
5531
5692
  return this;
5532
5693
  }
5533
- /**
5534
- * Appends columns or expressions to the existing select clause.
5535
- *
5536
- * @param select
5537
- * @returns
5538
- */
5539
5694
  addSelect(select) {
5540
5695
  const normalized = this.normalizeQuerySelect(select);
5541
5696
  if (normalized === null) throw new require_relationship.UnsupportedAdapterFeatureException("Select clauses must use Arkorm-normalizable column projections.", {
@@ -5559,6 +5714,8 @@ var QueryBuilder = class QueryBuilder {
5559
5714
  return this;
5560
5715
  }
5561
5716
  groupBy(...columns) {
5717
+ const first = columns[0];
5718
+ if (columns.length === 1 && this.isGroupByAggregateSpec(first)) return this.executeGroupByAggregate(first);
5562
5719
  const normalized = Array.isArray(columns[0]) ? columns[0] : columns;
5563
5720
  if (normalized.length === 0) throw new QueryConstraintException("groupBy requires at least one column.", {
5564
5721
  operation: "groupBy",
@@ -5567,6 +5724,109 @@ var QueryBuilder = class QueryBuilder {
5567
5724
  this.queryGroupBy = [...normalized];
5568
5725
  return this;
5569
5726
  }
5727
+ /**
5728
+ * Appends a raw SQL `group by` fragment (with positional `?` bindings), mirroring
5729
+ * `whereRaw`/`havingRaw`. Combines with any columns/expressions already grouped.
5730
+ *
5731
+ * @param sql
5732
+ * @param bindings
5733
+ * @returns
5734
+ */
5735
+ groupByRaw(sql, bindings = []) {
5736
+ this.queryGroupBy = [...this.queryGroupBy ?? [], { raw: {
5737
+ sql,
5738
+ bindings
5739
+ } }];
5740
+ return this;
5741
+ }
5742
+ /**
5743
+ * Resolves the recorded group-by sources into adapter {@link QueryGroupByItem}s.
5744
+ * A bare string that matches a select-column alias is expanded to that column's
5745
+ * underlying expression (group-by-alias); otherwise it is treated as a column.
5746
+ */
5747
+ buildGroupByItems(selectColumns) {
5748
+ if (!this.queryGroupBy || this.queryGroupBy.length === 0) return void 0;
5749
+ const expressionAliases = /* @__PURE__ */ new Map();
5750
+ selectColumns?.forEach((column) => {
5751
+ if (column.expression && column.alias) expressionAliases.set(JSON.stringify(column.expression), column.alias);
5752
+ });
5753
+ const aliasNames = new Set(expressionAliases.values());
5754
+ return this.queryGroupBy.map((source) => {
5755
+ if (source instanceof require_relationship.Expression) {
5756
+ const node = source.toExpressionNode();
5757
+ const alias = expressionAliases.get(JSON.stringify(node));
5758
+ return alias ? { alias } : { expression: node };
5759
+ }
5760
+ if (typeof source === "object") return { raw: source.raw };
5761
+ return aliasNames.has(source) ? { alias: source } : source;
5762
+ });
5763
+ }
5764
+ isGroupByAggregateSpec(value) {
5765
+ return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof require_relationship.Expression) && Array.isArray(value.by);
5766
+ }
5767
+ /**
5768
+ * Executes the query and returns plain, un-hydrated rows keyed by their select
5769
+ * alias — the natural shape for `select` + `groupBy` aggregate reports. Pass a
5770
+ * row type to describe the projection.
5771
+ *
5772
+ * @returns
5773
+ */
5774
+ async getRows() {
5775
+ return await this.executeReadRows();
5776
+ }
5777
+ /**
5778
+ * Runs a Prisma-style grouped aggregate and returns typed rows shaped as
5779
+ * `{ <by columns>, _sum, _avg, _min, _max, _count }`.
5780
+ */
5781
+ async executeGroupByAggregate(spec) {
5782
+ const selectMap = {};
5783
+ spec.by.forEach((column) => {
5784
+ selectMap[column] = true;
5785
+ });
5786
+ const aggregates = [];
5787
+ const register = (group, factory, map, numeric) => {
5788
+ Object.keys(map).forEach((column) => {
5789
+ if (!map[column]) return;
5790
+ const alias = `${group}_${column}`;
5791
+ selectMap[alias] = factory(column);
5792
+ aggregates.push({
5793
+ group,
5794
+ column,
5795
+ alias,
5796
+ numeric
5797
+ });
5798
+ });
5799
+ };
5800
+ if (spec._sum) register("_sum", (column) => require_relationship.sum(column), spec._sum, true);
5801
+ if (spec._avg) register("_avg", (column) => require_relationship.avg(column), spec._avg, true);
5802
+ if (spec._min) register("_min", (column) => require_relationship.min(column), spec._min, false);
5803
+ if (spec._max) register("_max", (column) => require_relationship.max(column), spec._max, false);
5804
+ let countAllAlias;
5805
+ if (spec._count === true) {
5806
+ countAllAlias = "_count_all";
5807
+ selectMap[countAllAlias] = require_relationship.count();
5808
+ } else if (spec._count) register("_count", (column) => require_relationship.count(column), spec._count, true);
5809
+ this.select(selectMap);
5810
+ this.groupBy(spec.by);
5811
+ return (await this.getRows()).map((row) => {
5812
+ const result = {};
5813
+ spec.by.forEach((column) => {
5814
+ result[column] = row[column];
5815
+ });
5816
+ const grouped = {};
5817
+ aggregates.forEach(({ group, column, alias, numeric }) => {
5818
+ grouped[group] ??= {};
5819
+ grouped[group][column] = numeric ? this.coerceNumeric(row[alias]) : row[alias];
5820
+ });
5821
+ Object.assign(result, grouped);
5822
+ if (countAllAlias) result._count = this.coerceNumeric(row[countAllAlias]);
5823
+ return result;
5824
+ });
5825
+ }
5826
+ coerceNumeric(value) {
5827
+ if (value === null || value === void 0) return null;
5828
+ return Number(value);
5829
+ }
5570
5830
  appendHavingCondition(boolean, condition) {
5571
5831
  if (!this.queryHaving) {
5572
5832
  this.queryHaving = condition;
@@ -5587,12 +5847,35 @@ var QueryBuilder = class QueryBuilder {
5587
5847
  value: hasOperator ? maybeValue : operatorOrValue
5588
5848
  };
5589
5849
  }
5590
- having(column, operatorOrValue, maybeValue) {
5591
- this.appendHavingCondition("AND", this.buildHavingComparison(operatorOrValue, maybeValue, column));
5850
+ /**
5851
+ * Resolves the three `having` call shapes into a condition: `having(column, )`,
5852
+ * `having(expression)` (a boolean expression predicate), and
5853
+ * `having(expression, operator, value)` (compare an aggregate to a value).
5854
+ */
5855
+ buildHavingCondition(columnOrExpression, operatorOrValue, maybeValue) {
5856
+ if (columnOrExpression instanceof require_relationship.Expression) return {
5857
+ type: "expression",
5858
+ expression: (operatorOrValue === void 0 ? columnOrExpression : this.compareExpression(columnOrExpression, operatorOrValue, maybeValue)).toExpressionNode()
5859
+ };
5860
+ return this.buildHavingComparison(operatorOrValue, maybeValue, columnOrExpression);
5861
+ }
5862
+ compareExpression(expression, operator, value) {
5863
+ switch (operator) {
5864
+ case "=": return expression.eq(value);
5865
+ case "!=": return expression.ne(value);
5866
+ case ">": return expression.gt(value);
5867
+ case ">=": return expression.gte(value);
5868
+ case "<": return expression.lt(value);
5869
+ case "<=": return expression.lte(value);
5870
+ default: return expression.eq(value);
5871
+ }
5872
+ }
5873
+ having(columnOrExpression, operatorOrValue, maybeValue) {
5874
+ this.appendHavingCondition("AND", this.buildHavingCondition(columnOrExpression, operatorOrValue, maybeValue));
5592
5875
  return this;
5593
5876
  }
5594
- orHaving(column, operatorOrValue, maybeValue) {
5595
- this.appendHavingCondition("OR", this.buildHavingComparison(operatorOrValue, maybeValue, column));
5877
+ orHaving(columnOrExpression, operatorOrValue, maybeValue) {
5878
+ this.appendHavingCondition("OR", this.buildHavingCondition(columnOrExpression, operatorOrValue, maybeValue));
5596
5879
  return this;
5597
5880
  }
5598
5881
  /**
@@ -5979,6 +6262,173 @@ var QueryBuilder = class QueryBuilder {
5979
6262
  return new require_relationship.ArkormCollection(filteredModels);
5980
6263
  }
5981
6264
  /**
6265
+ * Processes the query results in chunks, invoking the callback with each chunk
6266
+ * as a collection. Return `false` from the callback to stop early. Resolves to
6267
+ * `false` when stopped early, otherwise `true`.
6268
+ *
6269
+ * Chunking pages with `offset`/`limit`, so add an `orderBy` for stable results
6270
+ * and prefer {@link chunkById} when modifying the records being iterated.
6271
+ *
6272
+ * @param count Rows per chunk.
6273
+ * @param callback Receives each chunk and its 1-based page number.
6274
+ * @returns
6275
+ */
6276
+ async chunk(count, callback) {
6277
+ this.assertPositiveChunkSize(count, "chunk");
6278
+ let page = 1;
6279
+ for (;;) {
6280
+ const results = await this.clone().skip((page - 1) * count).take(count).get();
6281
+ const size = results.count();
6282
+ if (size === 0) break;
6283
+ if (await callback(results, page) === false) return false;
6284
+ if (size < count) break;
6285
+ page++;
6286
+ }
6287
+ return true;
6288
+ }
6289
+ /**
6290
+ * Chunks the results by comparing a monotonically increasing key column
6291
+ * (`id > lastId`) rather than by offset — safe when the callback updates the
6292
+ * records being iterated. Return `false` from the callback to stop early.
6293
+ *
6294
+ * @param count Rows per chunk.
6295
+ * @param callback Receives each chunk and its 1-based page number.
6296
+ * @param column The key column to page by (defaults to the primary key).
6297
+ * @param alias The result attribute holding the key value (defaults to `column`).
6298
+ * @returns
6299
+ */
6300
+ async chunkById(count, callback, column, alias) {
6301
+ this.assertPositiveChunkSize(count, "chunkById");
6302
+ const keyColumn = column ?? this.model.getPrimaryKey();
6303
+ const keyAlias = alias ?? keyColumn;
6304
+ let lastId = null;
6305
+ let page = 1;
6306
+ for (;;) {
6307
+ const builder = this.clone().take(count).orderBy({ [keyColumn]: "asc" });
6308
+ if (lastId !== null) builder.where({ [keyColumn]: { gt: lastId } });
6309
+ const results = await builder.get();
6310
+ const size = results.count();
6311
+ if (size === 0) break;
6312
+ if (await callback(results, page) === false) return false;
6313
+ lastId = this.readModelAttribute(results.last(), keyAlias);
6314
+ if (lastId === null || lastId === void 0) break;
6315
+ if (size < count) break;
6316
+ page++;
6317
+ }
6318
+ return true;
6319
+ }
6320
+ /**
6321
+ * Iterates the query results one record at a time (chunking under the hood).
6322
+ * Return `false` from the callback to stop early.
6323
+ *
6324
+ * @param callback Receives each record and its 0-based index.
6325
+ * @param count Rows fetched per chunk (default 1000).
6326
+ * @returns
6327
+ */
6328
+ async each(callback, count = 1e3) {
6329
+ let index = 0;
6330
+ return this.chunk(count, async (models) => {
6331
+ for (const model of models.all()) {
6332
+ if (await callback(model, index) === false) return false;
6333
+ index++;
6334
+ }
6335
+ });
6336
+ }
6337
+ /**
6338
+ * Like {@link each}, but pages by key column ({@link chunkById}) — safe when the
6339
+ * callback updates the records being iterated.
6340
+ *
6341
+ * @param callback Receives each record and its 0-based index.
6342
+ * @param count Rows fetched per chunk (default 1000).
6343
+ * @param column The key column to page by (defaults to the primary key).
6344
+ * @param alias The result attribute holding the key value (defaults to `column`).
6345
+ * @returns
6346
+ */
6347
+ async eachById(callback, count = 1e3, column, alias) {
6348
+ let index = 0;
6349
+ return this.chunkById(count, async (models) => {
6350
+ for (const model of models.all()) {
6351
+ if (await callback(model, index) === false) return false;
6352
+ index++;
6353
+ }
6354
+ }, column, alias);
6355
+ }
6356
+ /**
6357
+ * Streams the query results lazily as an async iterator, fetching one chunk at
6358
+ * a time so only a small window is held in memory. Iterate with `for await`.
6359
+ *
6360
+ * ```ts
6361
+ * for await (const user of User.query().orderBy({ id: 'asc' }).lazy()) {
6362
+ * // …
6363
+ * }
6364
+ * ```
6365
+ *
6366
+ * @param chunkSize Rows fetched per underlying query (default 1000).
6367
+ * @returns
6368
+ */
6369
+ async *lazy(chunkSize = 1e3) {
6370
+ this.assertPositiveChunkSize(chunkSize, "lazy");
6371
+ let page = 1;
6372
+ for (;;) {
6373
+ const items = (await this.clone().skip((page - 1) * chunkSize).take(chunkSize).get()).all();
6374
+ if (items.length === 0) break;
6375
+ yield* items;
6376
+ if (items.length < chunkSize) break;
6377
+ page++;
6378
+ }
6379
+ }
6380
+ /**
6381
+ * Streams the results lazily, paging by an ascending key column — safe when the
6382
+ * consumer updates records mid-iteration. Iterate with `for await`.
6383
+ *
6384
+ * @param chunkSize Rows fetched per underlying query (default 1000).
6385
+ * @param column The key column to page by (defaults to the primary key).
6386
+ * @param alias The result attribute holding the key value (defaults to `column`).
6387
+ * @returns
6388
+ */
6389
+ lazyById(chunkSize = 1e3, column, alias) {
6390
+ return this.lazyByKey(chunkSize, "asc", column, alias);
6391
+ }
6392
+ /**
6393
+ * Streams the results lazily, paging by a descending key column. Iterate with
6394
+ * `for await`.
6395
+ *
6396
+ * @param chunkSize Rows fetched per underlying query (default 1000).
6397
+ * @param column The key column to page by (defaults to the primary key).
6398
+ * @param alias The result attribute holding the key value (defaults to `column`).
6399
+ * @returns
6400
+ */
6401
+ lazyByIdDesc(chunkSize = 1e3, column, alias) {
6402
+ return this.lazyByKey(chunkSize, "desc", column, alias);
6403
+ }
6404
+ async *lazyByKey(chunkSize, direction, column, alias) {
6405
+ this.assertPositiveChunkSize(chunkSize, "lazyById");
6406
+ const keyColumn = column ?? this.model.getPrimaryKey();
6407
+ const keyAlias = alias ?? keyColumn;
6408
+ const operator = direction === "asc" ? "gt" : "lt";
6409
+ let lastId = null;
6410
+ for (;;) {
6411
+ const builder = this.clone().take(chunkSize).orderBy({ [keyColumn]: direction });
6412
+ if (lastId !== null) builder.where({ [keyColumn]: { [operator]: lastId } });
6413
+ const items = (await builder.get()).all();
6414
+ if (items.length === 0) break;
6415
+ yield* items;
6416
+ lastId = this.readModelAttribute(items[items.length - 1], keyAlias);
6417
+ if (lastId === null || lastId === void 0) break;
6418
+ if (items.length < chunkSize) break;
6419
+ }
6420
+ }
6421
+ assertPositiveChunkSize(count, operation) {
6422
+ if (!Number.isInteger(count) || count < 1) throw new QueryConstraintException("Chunk size must be a positive integer.", {
6423
+ operation,
6424
+ model: this.model.name
6425
+ });
6426
+ }
6427
+ readModelAttribute(model, attribute) {
6428
+ if (!model) return null;
6429
+ return model.getAttribute(attribute);
6430
+ }
6431
+ /**
5982
6432
  * Executes the query and returns the first result as a model
5983
6433
  * instance, or null if no results are found.
5984
6434
  *
@@ -6750,12 +7200,19 @@ var QueryBuilder = class QueryBuilder {
6750
7200
  }
6751
7201
  if (typeof select !== "object" || !select) return null;
6752
7202
  const entries = Object.entries(select);
6753
- if (entries.some(([, value]) => value !== true && value !== false && value !== void 0 && typeof value !== "string")) return null;
6754
- const columns = entries.filter(([, value]) => value === true || typeof value === "string").map(([column, value]) => typeof value === "string" ? {
6755
- column,
6756
- alias: value,
6757
- raw: true
6758
- } : { column });
7203
+ if (entries.some(([, value]) => value !== true && value !== false && value !== void 0 && typeof value !== "string" && !(value instanceof require_relationship.Expression))) return null;
7204
+ const columns = entries.filter(([, value]) => value === true || typeof value === "string" || value instanceof require_relationship.Expression).map(([column, value]) => {
7205
+ if (value instanceof require_relationship.Expression) return {
7206
+ column,
7207
+ alias: column,
7208
+ expression: value.toExpressionNode()
7209
+ };
7210
+ return typeof value === "string" ? {
7211
+ column,
7212
+ alias: value,
7213
+ raw: true
7214
+ } : { column };
7215
+ });
6759
7216
  return columns.length > 0 ? columns : [];
6760
7217
  }
6761
7218
  normalizeQueryOrderBy(orderBy) {
@@ -6913,7 +7370,7 @@ var QueryBuilder = class QueryBuilder {
6913
7370
  offset: normalizedQuery.offsetValue,
6914
7371
  columns: normalizedQuery.querySelect ? [...normalizedQuery.querySelect] : void 0,
6915
7372
  distinct: normalizedQuery.queryDistinct || void 0,
6916
- groupBy: normalizedQuery.queryGroupBy ? [...normalizedQuery.queryGroupBy] : void 0,
7373
+ groupBy: normalizedQuery.queryGroupBy ? normalizedQuery.queryGroupBy.filter((source) => typeof source === "string") : void 0,
6917
7374
  relationLoads: this.mergeRelationLoadPlans(normalizedQuery.queryRelationLoads ? this.cloneRelationLoads(normalizedQuery.queryRelationLoads) : void 0, this.mergeRelationLoadPlans(callbackRelationLoads, childRelationLoads))
6918
7375
  });
6919
7376
  }
@@ -7177,11 +7634,11 @@ var QueryBuilder = class QueryBuilder {
7177
7634
  if (columns === null || orderBy === null || condition === null) return null;
7178
7635
  if (this.hasRelationFilters() && this.canExecuteRelationFiltersInAdapter() && relationFilters === null) return null;
7179
7636
  if (this.hasRelationAggregates() && this.canExecuteRelationAggregatesInAdapter() && relationAggregates === null) return null;
7180
- return {
7637
+ return this.expandComputedAttributes({
7181
7638
  target: this.buildQueryTarget(),
7182
7639
  columns,
7183
7640
  distinct: this.queryDistinct || void 0,
7184
- groupBy: this.queryGroupBy ? [...this.queryGroupBy] : void 0,
7641
+ groupBy: this.buildGroupByItems(columns ?? void 0),
7185
7642
  having: this.queryHaving,
7186
7643
  joins: this.queryJoins ? [...this.queryJoins] : void 0,
7187
7644
  where: condition,
@@ -7191,7 +7648,86 @@ var QueryBuilder = class QueryBuilder {
7191
7648
  relationLoads: this.queryRelationLoads,
7192
7649
  relationFilters: this.canExecuteRelationFiltersInAdapter() ? relationFilters ?? void 0 : void 0,
7193
7650
  relationAggregates: this.canExecuteRelationAggregatesInAdapter() ? relationAggregates ?? void 0 : void 0
7651
+ });
7652
+ }
7653
+ /** Reads and caches the model's resolved `static computed` expression map. */
7654
+ computedAttributes() {
7655
+ const model = this.model;
7656
+ return typeof model.getComputed === "function" ? model.getComputed() : {};
7657
+ }
7658
+ /**
7659
+ * Expands references to `static computed` attribute names into their backing
7660
+ * expressions across a select spec's columns, group by, order by, where, and
7661
+ * having clauses. A no-op when the model declares no computed attributes.
7662
+ */
7663
+ expandComputedAttributes(spec) {
7664
+ const computed = this.computedAttributes();
7665
+ if (Object.keys(computed).length === 0) return spec;
7666
+ const columns = spec.columns?.map((column) => {
7667
+ if (column.expression || column.raw || column.wildcard) return column;
7668
+ const expression = computed[column.column];
7669
+ return expression ? {
7670
+ ...column,
7671
+ expression,
7672
+ alias: column.alias ?? column.column
7673
+ } : column;
7674
+ });
7675
+ const selectedComputedAliases = new Set(columns?.filter((column) => column.expression && column.alias).map((column) => column.alias));
7676
+ return {
7677
+ ...spec,
7678
+ columns,
7679
+ groupBy: spec.groupBy?.map((item) => {
7680
+ if (typeof item !== "string") return item;
7681
+ const expression = computed[item];
7682
+ if (!expression) return item;
7683
+ return selectedComputedAliases.has(item) ? { alias: item } : { expression };
7684
+ }),
7685
+ orderBy: spec.orderBy?.map((clause) => {
7686
+ if (clause.expression) return clause;
7687
+ const expression = computed[clause.column];
7688
+ return expression ? {
7689
+ ...clause,
7690
+ expression
7691
+ } : clause;
7692
+ }),
7693
+ where: spec.where ? this.expandComputedCondition(spec.where, computed) : spec.where,
7694
+ having: spec.having ? this.expandComputedCondition(spec.having, computed) : spec.having
7695
+ };
7696
+ }
7697
+ expandComputedCondition(condition, computed) {
7698
+ if (condition.type === "comparison" && computed[condition.column]) return {
7699
+ type: "expression",
7700
+ expression: this.computedComparison(computed[condition.column], condition.operator, condition.value)
7194
7701
  };
7702
+ if (condition.type === "group") return {
7703
+ ...condition,
7704
+ conditions: condition.conditions.map((entry) => this.expandComputedCondition(entry, computed))
7705
+ };
7706
+ if (condition.type === "not") return {
7707
+ ...condition,
7708
+ condition: this.expandComputedCondition(condition.condition, computed)
7709
+ };
7710
+ return condition;
7711
+ }
7712
+ /** Converts a where comparison against a computed attribute into an expression. */
7713
+ computedComparison(node, operator, value) {
7714
+ const expression = require_relationship.fromExpressionNode(node);
7715
+ const list = Array.isArray(value) ? value : [];
7716
+ switch (operator) {
7717
+ case "!=": return expression.ne(value).toExpressionNode();
7718
+ case ">": return expression.gt(value).toExpressionNode();
7719
+ case ">=": return expression.gte(value).toExpressionNode();
7720
+ case "<": return expression.lt(value).toExpressionNode();
7721
+ case "<=": return expression.lte(value).toExpressionNode();
7722
+ case "in": return expression.in(list).toExpressionNode();
7723
+ case "not-in": return expression.notIn(list).toExpressionNode();
7724
+ case "is-null": return expression.isNull().toExpressionNode();
7725
+ case "is-not-null": return expression.isNotNull().toExpressionNode();
7726
+ case "contains": return expression.like(`%${String(value)}%`).toExpressionNode();
7727
+ case "starts-with": return expression.like(`${String(value)}%`).toExpressionNode();
7728
+ case "ends-with": return expression.like(`%${String(value)}`).toExpressionNode();
7729
+ default: return expression.eq(value).toExpressionNode();
7730
+ }
7195
7731
  }
7196
7732
  tryBuildAggregateSpec() {
7197
7733
  const condition = this.buildQueryWhereCondition(false);
@@ -7691,6 +8227,9 @@ var Model = class Model {
7691
8227
  static {
7692
8228
  this.castMapCache = /* @__PURE__ */ new WeakMap();
7693
8229
  }
8230
+ static {
8231
+ this.computedCache = /* @__PURE__ */ new WeakMap();
8232
+ }
7694
8233
  static {
7695
8234
  this.emittedDeprecationWarnings = /* @__PURE__ */ new Set();
7696
8235
  }
@@ -7841,6 +8380,19 @@ var Model = class Model {
7841
8380
  return casts;
7842
8381
  }
7843
8382
  /**
8383
+ * Resolves the model's `static computed` declarations into expression nodes,
8384
+ * cached per class. Returns an empty map when no computed attributes exist.
8385
+ */
8386
+ static getComputed() {
8387
+ const cached = Model.computedCache.get(this);
8388
+ if (cached) return cached;
8389
+ const definitions = this.computed;
8390
+ const resolved = {};
8391
+ if (definitions) for (const [name, factory] of Object.entries(definitions)) resolved[name] = factory(require_relationship.expressionBuilder).toExpressionNode();
8392
+ Model.computedCache.set(this, resolved);
8393
+ return resolved;
8394
+ }
8395
+ /**
7844
8396
  * Apply built-in persistence casts (currently `json` serialisation) to a raw
7845
8397
  * attribute payload, without re-running arbitrary custom setters. Used by
7846
8398
  * both instance `save()` and the query-builder insert/update paths so a JS
@@ -9697,18 +10249,22 @@ var PivotModel = class extends Model {
9697
10249
  };
9698
10250
 
9699
10251
  //#endregion
10252
+ exports.AggregateExpression = require_relationship.AggregateExpression;
9700
10253
  exports.Arkorm = Arkorm;
9701
10254
  exports.ArkormCollection = require_relationship.ArkormCollection;
9702
10255
  exports.ArkormException = require_relationship.ArkormException;
9703
10256
  exports.Arkormx = Arkormx;
9704
10257
  exports.Attribute = Attribute;
10258
+ exports.CaseExpression = require_relationship.CaseExpression;
9705
10259
  exports.CliApp = CliApp;
9706
10260
  exports.DB = DB;
9707
10261
  exports.EnumBuilder = require_relationship.EnumBuilder;
10262
+ exports.Expression = require_relationship.Expression;
9708
10263
  exports.ForeignKeyBuilder = require_relationship.ForeignKeyBuilder;
9709
10264
  exports.InitCommand = InitCommand;
9710
10265
  exports.InlineFactory = InlineFactory;
9711
10266
  exports.JoinClause = JoinClause;
10267
+ exports.JsonExpression = require_relationship.JsonExpression;
9712
10268
  exports.KyselyDatabaseAdapter = KyselyDatabaseAdapter;
9713
10269
  exports.LengthAwarePaginator = require_relationship.LengthAwarePaginator;
9714
10270
  exports.MIGRATION_BRAND = MIGRATION_BRAND;
@@ -9756,6 +10312,7 @@ exports.applyMigrationToDatabase = require_relationship.applyMigrationToDatabase
9756
10312
  exports.applyMigrationToPrismaSchema = require_relationship.applyMigrationToPrismaSchema;
9757
10313
  exports.applyOperationsToPersistedColumnMappingsState = require_relationship.applyOperationsToPersistedColumnMappingsState;
9758
10314
  exports.applyOperationsToPrismaSchema = require_relationship.applyOperationsToPrismaSchema;
10315
+ exports.avg = require_relationship.avg;
9759
10316
  exports.awaitConfiguredModelsRegistration = require_relationship.awaitConfiguredModelsRegistration;
9760
10317
  exports.bindAdapterToModels = require_relationship.bindAdapterToModels;
9761
10318
  exports.buildEnumBlock = require_relationship.buildEnumBlock;
@@ -9769,8 +10326,12 @@ exports.buildModelBlock = require_relationship.buildModelBlock;
9769
10326
  exports.buildPrimaryKeyLine = require_relationship.buildPrimaryKeyLine;
9770
10327
  exports.buildRelationLine = require_relationship.buildRelationLine;
9771
10328
  exports.buildUniqueConstraintLine = require_relationship.buildUniqueConstraintLine;
10329
+ exports.caseWhen = require_relationship.caseWhen;
10330
+ exports.coalesce = require_relationship.coalesce;
10331
+ exports.col = require_relationship.col;
9772
10332
  exports.computeMigrationChecksum = require_relationship.computeMigrationChecksum;
9773
10333
  exports.configureArkormRuntime = require_relationship.configureArkormRuntime;
10334
+ exports.count = require_relationship.count;
9774
10335
  exports.createEmptyAppliedMigrationsState = require_relationship.createEmptyAppliedMigrationsState;
9775
10336
  exports.createEmptyPersistedColumnMappingsState = require_relationship.createEmptyPersistedColumnMappingsState;
9776
10337
  exports.createKyselyAdapter = createKyselyAdapter;
@@ -9791,12 +10352,15 @@ exports.deriveSingularFieldName = require_relationship.deriveSingularFieldName;
9791
10352
  exports.emitRuntimeDebugEvent = require_relationship.emitRuntimeDebugEvent;
9792
10353
  exports.ensureArkormConfigLoading = require_relationship.ensureArkormConfigLoading;
9793
10354
  exports.escapeRegex = require_relationship.escapeRegex;
10355
+ exports.expressionBuilder = require_relationship.expressionBuilder;
9794
10356
  exports.findAppliedMigration = require_relationship.findAppliedMigration;
9795
10357
  exports.findEnumBlock = require_relationship.findEnumBlock;
9796
10358
  exports.findModelBlock = require_relationship.findModelBlock;
10359
+ exports.fn = require_relationship.fn;
9797
10360
  exports.formatDefaultValue = require_relationship.formatDefaultValue;
9798
10361
  exports.formatEnumDefaultValue = require_relationship.formatEnumDefaultValue;
9799
10362
  exports.formatRelationAction = require_relationship.formatRelationAction;
10363
+ exports.fromExpressionNode = require_relationship.fromExpressionNode;
9800
10364
  exports.generateMigrationFile = require_relationship.generateMigrationFile;
9801
10365
  exports.getActiveTransactionAdapter = require_relationship.getActiveTransactionAdapter;
9802
10366
  exports.getActiveTransactionClient = require_relationship.getActiveTransactionClient;
@@ -9828,6 +10392,7 @@ exports.isDelegateLike = require_relationship.isDelegateLike;
9828
10392
  exports.isMigrationApplied = require_relationship.isMigrationApplied;
9829
10393
  exports.isQuerySchemaLike = require_relationship.isQuerySchemaLike;
9830
10394
  exports.isTransactionCapableClient = require_relationship.isTransactionCapableClient;
10395
+ exports.json = require_relationship.json;
9831
10396
  exports.loadArkormConfig = require_relationship.loadArkormConfig;
9832
10397
  exports.loadFactoriesFrom = require_relationship.loadFactoriesFrom;
9833
10398
  exports.loadMigrationsFrom = require_relationship.loadMigrationsFrom;
@@ -9835,7 +10400,10 @@ exports.loadModelsFrom = require_relationship.loadModelsFrom;
9835
10400
  exports.loadSeedersFrom = require_relationship.loadSeedersFrom;
9836
10401
  exports.markMigrationApplied = require_relationship.markMigrationApplied;
9837
10402
  exports.markMigrationRun = require_relationship.markMigrationRun;
10403
+ exports.max = require_relationship.max;
10404
+ exports.min = require_relationship.min;
9838
10405
  exports.pad = require_relationship.pad;
10406
+ exports.raw = require_relationship.raw;
9839
10407
  exports.readAppliedMigrationsState = require_relationship.readAppliedMigrationsState;
9840
10408
  exports.readAppliedMigrationsStateFromStore = require_relationship.readAppliedMigrationsStateFromStore;
9841
10409
  exports.readPersistedColumnMappingsState = require_relationship.readPersistedColumnMappingsState;
@@ -9852,6 +10420,7 @@ exports.resetRuntimeRegistryForTests = require_relationship.resetRuntimeRegistry
9852
10420
  exports.resolveCast = resolveCast;
9853
10421
  exports.resolveColumnMappingsFilePath = require_relationship.resolveColumnMappingsFilePath;
9854
10422
  exports.resolveEnumName = require_relationship.resolveEnumName;
10423
+ exports.resolveGeneratedExpression = require_relationship.resolveGeneratedExpression;
9855
10424
  exports.resolveMigrationClassName = require_relationship.resolveMigrationClassName;
9856
10425
  exports.resolveMigrationStateFilePath = require_relationship.resolveMigrationStateFilePath;
9857
10426
  exports.resolvePersistedMetadataFeatures = require_relationship.resolvePersistedMetadataFeatures;
@@ -9862,6 +10431,7 @@ exports.runArkormTransaction = require_relationship.runArkormTransaction;
9862
10431
  exports.runMigrationWithPrisma = require_relationship.runMigrationWithPrisma;
9863
10432
  exports.runPrismaCommand = require_relationship.runPrismaCommand;
9864
10433
  exports.stripPrismaSchemaModelsAndEnums = require_relationship.stripPrismaSchemaModelsAndEnums;
10434
+ exports.sum = require_relationship.sum;
9865
10435
  exports.supportsDatabaseCreation = require_relationship.supportsDatabaseCreation;
9866
10436
  exports.supportsDatabaseMigrationExecution = require_relationship.supportsDatabaseMigrationExecution;
9867
10437
  exports.supportsDatabaseMigrationState = require_relationship.supportsDatabaseMigrationState;
@@ -9869,7 +10439,9 @@ exports.supportsDatabaseReset = require_relationship.supportsDatabaseReset;
9869
10439
  exports.syncPersistedColumnMappingsFromState = require_relationship.syncPersistedColumnMappingsFromState;
9870
10440
  exports.toMigrationFileSlug = require_relationship.toMigrationFileSlug;
9871
10441
  exports.toModelName = require_relationship.toModelName;
10442
+ exports.val = require_relationship.val;
9872
10443
  exports.validatePersistedMetadataFeaturesForMigrations = require_relationship.validatePersistedMetadataFeaturesForMigrations;
10444
+ exports.where = require_relationship.where;
9873
10445
  exports.writeAppliedMigrationsState = require_relationship.writeAppliedMigrationsState;
9874
10446
  exports.writeAppliedMigrationsStateToStore = require_relationship.writeAppliedMigrationsStateToStore;
9875
10447
  exports.writePersistedColumnMappingsState = require_relationship.writePersistedColumnMappingsState;